У меня есть следующие упрощенные таблицы:
CREATE TABLE recipe(id int, name varchar(25));
CREATE TABLE ingredient(name varchar(25));
CREATE TABLE uses_ingredient(recipe_id int, name varchar(25));
Я хочу сделать запрос, который возвращает все id рецептов, содержащих как Chicken, так и Cream.
Я пробовал
SELECT recipe_id FROM uses_ingredient INNER JOIN
(SELECT * FROM ingredient WHERE name="Chicken" OR name="Cream")
USING (name) GROUP BY recipe_id
HAVING COUNT(recipe_id) >= (SELECT COUNT(*) FROM theme);
который дает мне: "ОШИБКА 1248 (42000): Каждая производная таблица должна иметь свой собственный псевдоним" и, вероятно, тоже ошибается.
Далее я попробовал
SELECT recipe_id FROM
(SELECT * FROM ingredient WHERE name="Chicken" OR name="Cream") AS t
INNER JOIN uses_ingredient USING (name)
GROUP BY recipe_id HAVING
COUNT(recipe_id)>= (SELECT COUNT(*) FROM t);
который дает "ERROR 1146 (42S02): Таблица" recipedb.t "не существует"
Я хочу избежать создания временных таблиц, включая использование ENGINE = MEMORY.
Другие предложения хороши, но вот другой способ. На самом деле это похоже на то, что вы пытались сделать в своем запросе. Хотя я не знаю, почему у вас есть таблица "ингредиент", когда одна и та же информация (имя), кажется, содержится в "use_ingredient".
SELECT recipe_id, count(*) c FROM uses_ingredient
WHERE name="Chicken" OR name="Cream"
GROUP BY recipe_id
HAVING c=2
Я согласен с MJB; это пересечение двух множеств. Поэтому я бы просто получил два набора и посмотрел, что в них обоих...
SELECT *
FROM recipe
WHERE EXISTS (SELECT *
FROM uses_ingredient
WHERE uses_ingredient.recipe_id = recipe.recipe_id AND
uses_ingredient.name = "Chicken") AND
EXISTS (SELECT *
FROM uses_ingredient
WHERE uses_ingredient.recipe_id = recipe.recipe_id AND
uses_ingredient.name = "Cream");
Вероятно, есть лучший способ подумать об этом, но я вижу ответ как пересечение двух наборов: те рецепты, в которых есть курица и те рецепты, в которых есть крем. Это может не сработать для вас, если вы упростите больше, чем просто количество столбцов. Но я попробовал это с горсткой записей, и это кажется прекрасным.
SELECT CH.Recipe_Id
FROM
(SELECT Recipe_Id
FROM Uses_Ingredient
WHERE Name = 'Chicken') CH
INNER JOIN
(SELECT Recipe_Id
FROM Uses_Ingredient
WHERE Name = 'Cream') CR
ON CR.Recipe_Id = CH.Recipe_Id