2016-12-01 3 views
1

Я пытаюсь выбрать все рецепты, которые содержат заданное количество ингредиентов. Я в состоянии найти все рецепты, основанные на одной заданной recipe_id с:SQL - запрос многих-ко-многим

SELECT name 
FROM recipe 
INNER JOIN recipe_ingredient 
ON recipe.recipe_id = recipe_ingredient.recipe_id 
WHERE recipe_ingredient.recipe_id = ? 

Но у меня возникают проблемы выяснить, что запрос должен выглядеть, когда я ищу рецепты, которые содержат больше, чем содержать более одного конкретного ингредиента. Для примера Ингредиент A и B. Ингредиент

Мои таблицы выглядеть следующим образом:

ingredient 
    -ingredient_id 
    -name 

recipe_ingredient 
    -recipe_ingredient 
    -ingredient_id 
    -recipe_id 


recipe 
    -recipe_id 
    -name 

Я был бы очень рад, о каких-либо идей о том, как решить эту проблему! Спасибо.

+1

Существует различие, чтобы быть здесь. Вы хотите, чтобы все Рецепты имели более одного ингредиента, независимо от того, какие ингредиенты есть? Или вы хотите, чтобы все рецепты, содержащие конкретные ингредиенты? Это не ясно из вашего вопроса, но есть ответы, чтобы ответить на оба вопроса: – EoinS

+0

Вы правы, мой вопрос был недостаточно ясным. Простите за это. Я ищу все рецепты, содержащие специфический ингредиент! – ArtemisUser

+0

Хорошо - я обновил свой ответ на основе этого комментария – kbball

ответ

-1

Использования группы по и имеющий пункт

SELECT name 
FROM recipe 
INNER JOIN recipe_ingredient 
ON recipe.recipe_id = recipe_ingredient.recipe_id 
GROUP BY name 
HAVING count(1) > 1 
+0

Ваша группа должна быть на имя. Я уверен, что это выкинет ошибку, как написано – kbball

+0

Да, я думал, что то же самое, просто для упрощения запроса, спасибо :) –

0

Ваш запрос будет выглядеть как этот

Your query will look something like this 

SELECT name, count(*) 
FROM recipe 
INNER JOIN recipe_ingredient 
ON recipe.recipe_id = recipe_ingredient.recipe_id 
GROUP BY name 
HAVING count(*) > 1 
0

Для того, чтобы соответствовать всем элементов в IN статьи, вы должны убедиться, что вы выберите только Рецепты с count, которые соответствуют общему количеству ингредиентов в вашем списке:

SELECT name 
FROM recipe 
INNER JOIN recipe_ingredient 
ON recipe.recipe_id = recipe_ingredient.recipe_id 
WHERE recipe_ingredient.ingredient_id IN (ID1, ID2, ID3) --list of ingredient IDs 
Group By Name 
Having Count(*) = 3 --# of Ingredients you have chosen 

Удачи найти рецепт которого будет работать с ингредиентами, вы имеете в наличии

Here is a functional example

+0

, когда я меняю последнюю строку 'WHERE recipe_ingredient.recipe_id IN (ID1, ID2, ID3) 'to' WHERE recipe_ingredient.ingredient_id IN (ID1, ID2, ID3) 'он дает мне все рецепты, содержащие хотя бы один из этих идентификаторов! Так что это большой шаг в правильном направлении для меня. Но теперь мой вопрос заключается в том, как получить только те рецепты, которые содержат по крайней мере все данные ингредиенты, а не только подмножество данных. – ArtemisUser

+0

@ArtemisUser благодарит за указание, что это должно быть 'componentient_id'. Я просто обновил ответ, чтобы убедиться, что вы сопоставляете ВСЕ элементы в списке – EoinS

-1

Просто используйте OR для where. Как это

$query = "SELECT name 
FROM recipe 
INNER JOIN recipe_ingredient 
ON recipe.recipe_id = recipe_ingredient.recipe_id 
WHERE recipe_ingredient.recipe_id = ? OR recipe_ingredient.recipe_id = ?"; 
0

IF ищет конкретные ингредиенты, вы можете сделать предварительный запрос делает объединение всех ингредиентов, которые вы заинтересованы. Присоединяйтесь, что к столу ингредиентов в рецептуре и убедитесь, что все ингредиенты приходилось. Это обрабатывается группой и имеет счет = количество ингредиентов, которые вы ищете.

Я сделал этот пример, основываясь на названии ингредиента. Если у вас есть/знаете фактический идентификатор ингредиента (который будет более точным, например, на веб-сайте, и у вас есть идентификаторы, выбранные пользователем), просто измените условие соединения на идентификатор ингредиента, а не только на описание ингредиента.

SELECT 
     r.name, 
     r.recipe_id 
    from 
     (SELECT 'Milk' as Ingredient 
      UNION select 'Eggs' 
      UNION select 'Butter') as Wanted 
     JOIN recipe_ingredient ri 
      ON Wanted.Ingredient = ri.recipe_ingredient 
      JOIN Recipe r 
       ON ri.Recipe_id = r.id 
    group by 
     ri.recipe_id 
    having 
     COUNT(*) = 3 

В этом случае, молоко, масло, яйца и окончательный подсчет = 3.