我有一个有三个表的数据库:recipes、ingredients和allergens。recipes和ingredients以及ingredients和allergens之间都有很多关系.这些关系是通过中间表ingredient_in_recipe和allergen_in_ingredient解决的,它们只包含食谱、成分和过敏原各自的ids。
现在,在一组菜谱中选择所有成分很简单,例如,对于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 JOIN和WHERE子句,以从结果数据集中删除某些成分。然而,当食谱中含有特定过敏原的成分时,我想从任何含有过敏原的食谱的结果中删除所有匹配的成分,因为该配方由于过敏而不再有效。实现这一目标的最佳途径是什么?
发布于 2015-01-18 18:31:12
以下查询获得没有过敏原的“安全”食谱:
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表来获得“安全”菜谱。
然后,你可以把它加入到配料中,用它们的神奇成分获得安全的食谱:
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;发布于 2015-01-21 18:43:36
这是我最后得到的解决方案。我没有在问题中清楚地说明这一点,但最好从清单中删除任何含有过敏原成分的配方。在下面的所有菜谱和含有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;https://stackoverflow.com/questions/28013147
复制相似问题