Группировка результатов после объединения и предложение - PullRequest
1 голос
/ 14 октября 2019

Допустим, у меня есть три таблицы (mysql):

рецепты

+----+----------------+--------------+
| id |     title      |   image      |
+----+----------------+--------------+
|  2 | recipe title 1 | banana image |
|  3 | recipe title 2 | potato image |
+----+----------------+--------------+

ингредиент

+----+-----------+---------+---------------+
| id | recipe_id | food_id | quantity_kg   |
+----+-----------+---------+---------------+
|  1 |         2 |      36 | 2.5           |
|  2 |         3 |      37 | 1.5           |
+----+-----------+---------+---------------+

food

+----+---------+-------+-----------+----------+
| id |  name   | price | foodType  | unitType |
+----+---------+-------+-----------+----------+
| 36 | carrot  |     2 | vegetable | kg       |
| 37 | chicken |    12 | meat      | kg       |
+----+---------+-------+-----------+----------+

Теперь я хочу получить все вегетарианские рецепты, то есть не содержащие продуктов, где foodType - это «мясо» (или другой продукт животного происхождения). .

Как мне выполнить такой запрос?

Вот что я пробовал до сих пор:

SELECT
  recipe.id as recipeId,
  recipe.title as title,
  food.type as foodType
FROM recipe
INNER JOIN ingredient on ingredient.recipe_id = recipe.id
INNER JOIN food on food.id = ingredient.aliment_id
HAVING 
  food.type <> 'meat' AND
  food.type <> 'seafood' AND
  food.type <> 'fish' 
ORDER BY recipeId

Это работает (я получаю только вегетарианские рецепты), НО этодублирует все рецепты, если они имеют несколько ингредиентов. например. :

+----------+--------+----------+
| recipeId | title  | foodType |
+----------+--------+----------+
|        5 | titleA | type1    |
|        5 | titleA | type2    |
|        5 | titleA | type3    |
|        8 | titleB | type2    |
|        8 | titleB | type5    |
|        8 | titleB | type1    |
|        8 | titleB | type3    |
+----------+--------+----------+

Что я хочу получить:

+----------+--------+
| recipeId | title  |
+----------+--------+
|        5 | titleA |
|        8 | titleB |
+----------+--------+

Я уже пытался избавиться от 'foodType' в предложении SELECT, но если я это сделаю, mysql скажет мне:"Неизвестный столбец 'food.type' в 'имеющем предложении'"

Я уже пытался GROUP BY 'recipeId' прямо перед предложением HAVING, но я получаю эту ошибку: "Выражение № 3 из списка SELECT отсутствует вПредложение GROUP BY и содержит неагрегированный столбец «myDb.food.type», который функционально не зависит от столбцов в предложении GROUP BY »(я понимаю эту ошибку).

Я полагаю, это связано с чем-то вроде« Группировкарезультаты после объединения и с предложением ", но я могу ошибаться ...

Большое спасибо

Ответы [ 2 ]

0 голосов
/ 14 октября 2019

только исключите все рецепты, в которых есть хотя бы один мясной ингредиент (я сделал это 10 лет назад, даже без sql)

SELECT recipe.id, recipe.title FROM recipe
WHERE recipe.id NOT IN (
   SELECT
      recipe.id,
   FROM recipe
   INNER JOIN ingredient 
      on ingredient.recipe_id = recipe.id
   INNER JOIN food 
      on food.id = ingredient.aliment_id
      AND food.type IN ('meat', 'seafood', 'fish') 
)
ORDER BY recipeId
0 голосов
/ 14 октября 2019
  • У вас нет предложения GROUP BY, поэтому у вас не должно быть предложения HAVING. Используйте WHERE вместо
  • Удалите ненужные столбцы из вашего SELECT
  • Поскольку объединения имеют отношение 1: много связей, но вы выбираете только одну сторону, вы, вероятно,также хотите SELECT DISTINT вместо просто SELECT

Кроме того, у вас есть еще одна проблема: логика вашего запроса на самом деле не верна, даже если он возвращает явно правильные результаты с таким небольшим наборомобразца данных.

При просмотре композиции вы, вероятно, захотите использовать EXISTS и подзапрос. Возможно, что-то вроде этого (не проверено):

SELECT
  recipe.id as recipeId,
  recipe.title as title,
  food.type as foodType
FROM recipe r
WHERE NOT EXISTS
  (SELECT food.type
   FROM ingredient INNER JOIN food on food.id = ingredient.aliment_id
   WHERE ingredient.recipe_id = r.id AND 
      food.type IN ('meat', 'seafood','fish')
  )
ORDER BY recipeId
...