@hesy

Как отсортировать результат по количеству «пойманных» id?

Не знаю как корректно еще назвать вопрос)

Есть таблица recipe_ingredients:
+----+-----------+---------------+
| id | recipe_id | ingredient_id |
+----+-----------+---------------+
| 1  | 100       | 500           |
+----+-----------+---------------+
| 2  | 100       | 501           |
+----+-----------+---------------+
| 3  | 200       | 501           |
+----+-----------+---------------+
| 4  | 200       | 900           |
+----+-----------+---------------+
| 5  | 200       | 901           |
+----+-----------+---------------+


Как при выборке отсортировать результаты по количеству наличия ingredient_id с одним recipe_id (назвать поле, например, catch_ingredients)?
SELECT 
  recipe_id, 
  catch_ingredients 
FROM 
  recipe_ingredients
WHERE 
  ingredient_id IN (501, 900) 
GROUP BY 
  recipe_id 
ORDER BY 
  catch_ingredients DESC


Чтобы получить такой результат:
+-----------+-------------------+
| recipe_id | catch_ingredients |
+-----------+-------------------+
| 200       | 2                 | <--- Поймали 501 и 900 
+-----------+-------------------+
| 100       | 1                 | <--- Поймали только 501
+-----------+-------------------+


Моих знаний SQL не хватает для реализации этого..
Скорее всего, здесь требуется не оператор IN.

Объясню простым языком, что я хотел сделать:
Есть условно холодильник с множеством ingredient_id.
Нужно достать из него все recipe_id, где встречаются ingredient_id (составить список релевантных рецептов из доступных продуктов), НО, рецепту не обязательно содержать все передаваемые ингредиенты (например, передали лук, картошку, курицу, сахар, апельсин, показали рецепты с "картошка с курицей" и "сок из апельсина")
В случае с ingredient_id IN ... он выбирает где строго должны быть все перечисленные айди.

recipe_id, ingredient_id имеют отношения с другими таблицами

ps, пилю пет-проект ради интереса, но на главной фиче застопорился и туплю)
  • Вопрос задан
  • 96 просмотров
Пригласить эксперта
Ответы на вопрос 2
SELECT value, COUNT(*)
FROM table
GROUP BY 1
ORDER BY 2 DESC
Ответ написан
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Так какой вопрос то стоит?
"Найти рецепты, в которые входит хотя бы один ингредиент из списка?
SELECT `recipe_id`, `ingredient_id`
  FROM `recipe_ingredients`
  WHERE `ingredient_id` IN (501, 900)

"Рецепт можно приготовить из указанных ингредиентов"? Значит все ингредиенты данного рецепта присутствуют в заданном списке. То есть, общее количество ингредиентов рецепта равно количеству ингредиентов этого рецепта, присутствующих в списке.
SELECT `recipe_id`, COUNT(*) AS `count`,
    SUM(`ingredient_id` IN (501, 900)) AS `avail`
  FROM `recipe_ingredients`
  GROUP BY `recipe_id`
  HAVING `count` = `avail`

P.S.
А поле `id` в таблице лишнее. Достаточно составного первичного ключа (`recipe_id`, `ingredient_id`).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы