w3shivers
w3shivers

Reputation: 400

MySQL join 3 tables, with multiple columns excluding results from one table

I’m trying to join 3 tables in MySQL, and need some help.

My first table is a list of recipes.

**recipes**
RecipeID | RecipeName
1        | Cheese and Ham Toasty
2        | 20 Minute Pasta
3        | Minute Steak

The second table is a list of ingredients assign to the recipes table

**ingredients**
RecipeID | IngredientID | IngredientName
1        | 1            | Cheese
1        | 2            | Bread
1        | 3            | Ham
1        | 4            | Butter
2        | 5            | Pasta
2        | 6            | Mince
2        | 1            | Cheese
3        | 8            | Steak
3        | 9            | BBQ Sauce

The third table is a table that users can use to add ingredients they don’t want to see recipes of, for now only one ingredient for the user

**usersList**
IngredientID | userID
1            | 2

And my result when joining the tables should be as follows:

**recipes**
RecipeID | RecipeName
3        | Minute Steak

However my result is either all the recipes I don’t want or an empty result. Below is the MySQL that I’m using that currently supplies me with all the recipes I don’t want.

SELECT RecipeID, RecipeName FROM recipes LEFT JOIN ingredients
INNER JOIN usersList ON ingredients.IngredientID = usersList.IngredientID 
ON recipes.RecipeID = ingredients.RecipeID
WHERE recipes.RecipeID IS NOT NULL
AND usersList.userID = 2
GROUP BY recipes.RecipeID

How can I join these tables so that I get all recipes that don’t include any of the recipes that have ingredients in the user list and still supplies results if the user has no ingredients listed? Thanks in advance for helping.

Upvotes: 2

Views: 41

Answers (3)

isaace
isaace

Reputation: 3429

You can also use a left join here as follows:

select r.RecipeID, r.RecipeName from recipes r
left join (select RecipeID from ingredients i
          join  usersList u on u.RecipeID = i.RecipeID) as u
          on u.RecipeID = r.RecipeID
where u.RecipeID is null

Upvotes: 0

Thorsten Kettner
Thorsten Kettner

Reputation: 94894

You are not looking for a join. You want to see recipes for which not exists a certain ingrediant. So select from the recipes table and limit the results with NOT EXISTSor NOT IN in the WHERE clause. Here is a simple solution with two IN clauses:

select *
from recipes
where recipeid not in
(
  select recipeid
  from ingredients
  where ingredientid in
  (
    select ingredientid 
    from userslist
    where userid = 2
  )
);

Upvotes: 3

symcbean
symcbean

Reputation: 48357

Use an inner join between recipes and ingredients, a left join between ingredients and userlists, then in the exclude results where the Primary key returned from the userlist is not null.

The output of this will include multiple entries for recipes with multiple ingredients - which may need tidying....

SELECT recipename, GROUP_CONCAT(ingredient_name), 
  SUM(IF(userlist.ingredientid IS NULL, 0, 1))
FROM recipes
INNER JOIN ingredients
ON recipes.recipeid=ingredients.ingredientid
LEFT JOIN userlist
ON ingredients.ingredientid=userlist.ingredientid
AND userlist.userid=_______
GROUP BY recipename
HAVING SUM(IF(userlist.ingredientid IS NULL, 0, 1))=0

Upvotes: 0

Related Questions