Reputation: 173
I've got the following tables in my Database:
dishes
id
name
users
id
email
ingredients
id
name
dishes_ingredients (this is used to represent the relation between dishes and ingredients)
id
dish_id
ingredient_id
users_allergic_ingredients (users are allergic to certain ingredients)
id
user_id
ingredient_id
Given a certain user (user_id), I need to get all the dishes to which the user is NOT allergic to.
I tried with this query:
SELECT *
FROM dishes
JOIN dishes_ingredients
ON dishes.id = dishes_ingredients.dish_id
WHERE dishes_ingredients.ingredient_id NOT IN
(SELECT uai.ingredient_id FROM users_allergic_ingredients uai WHERE uai.user_id = 1)
But I get all the dishes and not only the dishes to which the customer is not allergic to.
What am I doing wrong?
Upvotes: 0
Views: 61
Reputation: 19
It sounds wired, but you can use left join to users_allergic_ingredients and get only the rows the join to didn't succeed. like this -
SELECT D.name
FROM dishes D
INNER JOIN dishes_ingredients DI
ON D.id = DI.dish_id
LEFT OUTER JOIN users_allergic_ingredients UAI
ON UAI.user_id = @user_id
and UAI.ingridient_id = DI.ingridient_id
WHERE UAI.ingridient_id IS NULL
notice the WHERE who deliberately asks the rows that were left out
Upvotes: 0
Reputation: 1269733
Your are getting ingredients that are absent, not dishes.
I would approach this using aggregation:
SELECT di.dish_id
FROM dishes_ingredients di LEFT JOIN
users_allergic_ingredients uai
ON uai.ingredient_id = di.ingredient_id AND
uai.user_id = 1
GROUP BY di.dish_id
HAVING COUNT(uai.integredient_id) = 0;
The FROM
clause matches uai
when the user is allergic to the ingredient. The HAVING
clause just determines that the count is zero.
Upvotes: 1