MySQL:如果满足条件,则排除匹配

时间:2015-01-18 18:19:32

标签: mysql

我有一个包含三个表的数据库:recipesingredientsallergensrecipesingredients以及ingredientsallergens之间存在多对多关系。这些关系使用中间表ingredient_in_recipeallergen_in_ingredient来解决,这些中间表仅包含配方,成分和过敏原的相应ID。

现在,选择一组食谱中的所有食材很简单,例如id = 1,2,3,4和5的食谱就像这样:

SELECT i.* FROM ingredients AS i
    INNER JOIN ingredient_in_recipe AS ir ON i.id = ir.ingredient_id
    INNER JOIN recipes AS r ON ir.recipe_id = r.id
WHERE r.id IN (1, 2, 3, 4, 5);

此外,很容易添加更多INNER JOINWHERE子句以从结果数据集中删除某些成分。然而,当食谱中含有某种过敏原的成分时,我想从结果中删除所有匹配的成分,因为该过敏原中含有该过敏原的食谱,因为该食谱因过敏而不再有效。实现这一目标的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

以下查询获得" safe"没有过敏原的食谱:

SELECT ir.recipe_id
FROM ingredient_in_recipe ir LEFT JOIN
     allergens_in_ingredient ai
     ON ai.ingredient_id = i.id
WHERE ir.recipe_id IN (1, 2, 3, 4, 5)
GROUP BY ir.recipe_id
HAVING MAX(ai.allergen_id IS NULL) IS NULL;

请注意,您不需要recipes表或ingredients表来获取" safe"配方

然后,您可以将其与成分一起加入,以便与他们的不满者一起获得安全食谱:

SELECT i.*
FROM (SELECT ir.recipe_id
      FROM ingredient_in_recipe ir LEFT JOIN
           allergens_in_ingredient ai
           ON ai.ingredient_id = i.id
      WHERE ir.recipe_id IN (1, 2, 3, 4, 5)
      GROUP BY ir.recipe_id
      HAVING MAX(ai.allergen_id IS NULL) IS NULL
     ) rsafe JOIN
     ingredient_in_recipe ir
     ON rsafe.recipe_id = ir.recipe_id JOIN
     ingredients i INNER JOIN
     ON i.id = ir.ingredient_id
ORDER BY i.recipe_id;

答案 1 :(得分:0)

这是我最终解决的问题。我没有在问题中明确说明,但是最好从列表中删除任何含有过敏原成分的配方。在下面,它在所有食谱和任何包含id为1,2或4的过敏原的配方中进行搜索。因为我不需要来自recipe表的任何数据,所以它被排除在最后一部分之外。查询。

SELECT i.*, ir.*
FROM(SELECT ir.recipe_id
    FROM ingredient_in_recipe AS ir LEFT JOIN 
        allergen_in_ingredient AS ai ON ai.ingredient_id = ir.ingredient_id
    GROUP BY ir.recipe_id
    HAVING NOT MAX(ai.allergen_id IN (1, 2, 14))
    ) AS rsafe LEFT JOIN
        ingredient_in_recipe AS ir ON rsafe.recipe_id = ir.recipe_id INNER JOIN
        ingredients AS i on i.id = ir.ingredient_id
ORDER BY i.id;