Reputation: 33
I'm wondering if it's possible to do the something with a single mysql query and if so, then curious about your thoughts on the most efficient way of doing it.
I have a table with two fields...let's say recipe and ingredient
I'm looking for all recipes that have a subset of ingredients of a given recipe.
To illustrate that:
Recipe | Ingredient
-------------------
sandwich | bread
sandwich | lettuce
sandwich | mustard
sandwich | bacon
sandwich | tomato
bacon salad | lettuce
bacon salad | tomato
bacon salad | bacon
veggie salad | lettuce
veggie salad | tomato
veggie salad | cucumber
I'm passing in "sandwich" as a parameter and need a query that will return the bacon salad (i.e. the ingredients are all included in the list of sandwich ingredients), but not the veggie salad, as it contains cucumber, which is not in the sandwich.
I reviewed this Q:
SQL query to exclude records that appear in other rows?
but I think that my case is different and more complicated. It would be similar if I was passing in "bacon" and excluding all recipes that contain ingredients other than "bacon", but I need to generate the list of what I'm excluding based on a query of the input recipe ingredients.
Hope that makes sense! I feel like this should be fairly trivial but am stuck.
TIA for you help!
Upvotes: 2
Views: 433
Reputation: 1311
lets say table name is kitchen
select * from kitchen k0 where Recipe NOT IN
(
select * from kitchen k1 where Recipe!="sandwitch" and
ingredient NOT IN (select k2.ingredient from kitchen k2 where Recipe="sandwitch"))
Explanation:
Upvotes: 0
Reputation: 3993
This works for Sql Server. I am sure there is an equivalent in MySql
Drop Table #Test1
Create Table #Test1 (Recipe Varchar(8000), Ingredient Varchar(8000))
Insert #Test1 Values ('sandwich', 'bread')
Insert #Test1 Values ('sandwich', 'lettuce')
Insert #Test1 Values ('sandwich', 'mustard')
Insert #Test1 Values ('sandwich', 'bacon')
Insert #Test1 Values ('sandwich', 'tomato')
Insert #Test1 Values ('bacon salad ', 'lettuce')
Insert #Test1 Values ('bacon salad ', 'tomato')
Insert #Test1 Values ('bacon salad', 'bacon')
Insert #Test1 Values ('veggie salad', 'lettuce')
Insert #Test1 Values ('veggie salad', 'tomato')
Insert #Test1 Values ('veggie salad', 'cucumber')
;With cteQuery As
(
Select T.*, A.Ingredient IngredientMatch
From #Test1 T
Left Join (
Select Ingredient
From #Test1
Where Recipe = 'Sandwich'
) A On A.Ingredient = T.Ingredient
Where Recipe != 'Sandwich'
)
Select Distinct Recipe From cteQuery Where Recipe Not In
(Select Recipe From cteQuery Where IngredientMatch Is Null)
Upvotes: 0
Reputation: 133370
Could be you need an inner join
select distinct a.Recipe
from my_table as a
inner my_table as b on a.ingredient = b.ingredient;
Upvotes: 0
Reputation: 1269873
You want to count the number of ingredients that are the same. You can do this using a left join
and aggregation:
select i.recipe
from ingredients i left join
ingredients i2
on i.ingredient = i2.ingredient and i2.recipe = 'sandwich' and
i.recipe <> i2.recipe
group by i.recipe
having count(*) = count(i2.ingredient);
The having
clause checks that all ingredients have a match for sandwich
.
Upvotes: 2