MySQL: запрос для получения рецептов с использованием всех заданных ингредиентов - PullRequest
0 голосов
/ 10 июня 2010

У меня есть следующие упрощенные таблицы:

CREATE TABLE recipe(id int, name varchar(25));  
CREATE TABLE ingredient(name varchar(25));  
CREATE TABLE uses_ingredient(recipe_id int, name varchar(25));

Я хочу сделать запрос, который возвращает все идентификаторы рецептов, которые содержат как курицу, так и сливки.

Я пробовал

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);

, что дает "ОШИБКА 1146 (42S02): таблица 'receedb.t' не существует"

Я хочу избежать создания временных таблиц, в том числе с использованием ENGINE = MEMORY.

Ответы [ 3 ]

0 голосов
/ 11 июня 2010

Я согласен с 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");
0 голосов
/ 11 июня 2010

Другие предложения хороши, но есть и другой способ. На самом деле это похоже на то, что вы пытались сделать в своем запросе. Хотя я не знаю, почему у вас есть и таблица «ингредиент», когда одна и та же информация (имя), кажется, содержится в «Use_ingredient».

SELECT recipe_id, count(*) c FROM uses_ingredient
WHERE name="Chicken" OR name="Cream"
GROUP BY recipe_id
HAVING c=2
0 голосов
/ 10 июня 2010

Вероятно, есть лучший способ думать об этом, но я вижу ответ в виде пересечения двух наборов: тех рецептов, в которых есть курица, и тех рецептов, в которых есть сливки. Это может не сработать, если вы упростили не только количество столбцов. Но я попробовал это с кучей записей, и это выглядит нормально.

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
...