开发者

search in joint tables

I have four tables:

cuisines(id, name);

recipes(id, cuisine_id, name, picture);

ingredients(id, name);

ingredients_recipes(ingredient_id, recipe_id);
开发者_运维技巧

the last table references the Many-To-Many relationship between recipes and ingredients. How can I select all cuisines which contain tomatoes (i.e. the cuisine has recipes which have ingredients which are called "tomatoes")?

I am using this in SQLite but I guess it's the same in all SQL languages?


You may want to try INNER JOINing all four tables, as in the following example:

SELECT      DISTINCT c.name
FROM        cuisines AS c
INNER JOIN  recipes AS r ON (r.cuisine_id = c.id)
INNER JOIN  ingredients_recipes AS ir ON (ir.recipe_id = r.id)
INNER JOIN  ingredients AS i ON (i.id = ir.ingredient_id)
WHERE       i.name = 'tomatoes';


Join them all according to the foreign keys, filter on ingredient_name = 'Tomatoe', group by all columns of the cuisines table you're interested in.

SELECT cuisine.id, cuisine.name
  FROM cuisine
  INNER JOIN recipe on recipe.cuisine_id = cuisine.id
  INNER JOIN ingredients_recipes ir ON ir.recipe_id = recipe.id
  INNER JOIN ingredients on ingredients.id = ir.ingredient_id
  WHERE ingredients.name = 'Tomatoe'
  GROUP BY cuisine.id, cuisine.name


Subquery variant:

SELECT name
FROM cuisines
WHERE id IN (
    SELECT cuisine_id 
    FROM recipes r 
    JOIN ingredients_recipes ir ON r.id = ir.recipe_id
    JOIN ingredients i ON ir.ingredient_id = i.id
    WHERE i.name = 'Tomatoes'
)


I'd suggest using subqueries instead of the joins. Something like...

SELECT *
    FROM cuisine
    WHERE cuisine_id IN (
             SELECT cuisine_id
                 FROM recipe
                 WHERE recipe_id IN (
                         SELECT recipe_id
                             FROM recipe_ingredients
                             WHERE ingredient_id IN (
                                        SELECT id
                                        FROM ingredients
                                        WHERE TOUPPER(name) LIKE '%TOMATO%')));

In any case, I think you have to be careful with the match on the word; more so than other correspondents have been, as you don't want to miss ingredients like 'Four small tomatoes' or 'One large tomato' or 'Tomato puree'.


EXISTS variant:

SELECT name
FROM cuisines c
WHERE EXISTS
(   SELECT NULL 
    FROM recipes r 
    JOIN ingredients_recipes ir ON r.id = ir.recipe_id
    JOIN ingredients i ON ir.ingredient_id = i.id and i.name = 'tomatoes'
    WHERE r.cuisine_id = c.id
)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜