关于我的第一个问题"Show recipe name if all of its ingredients are already given"
我的第一个问题询问在给出所有成分时显示配方,接下来的事情与第一个相同,但它需要显示配方(具有与第一个相同的给定成分)和还有一些成分能够完成这个配方。对不起,我的英语不好。我希望你知道我的意思。
答案 0 :(得分:2)
为了根据成分列表查找食谱列表,食谱必须含有这些成分但也可以含有更多成分,您可以尝试这样的事情:
SELECT R.name
FROM Recipe R, Ingredients I, Relationship Rel
WHERE I.ingredients_name = 'Chicken' AND Rel.ingredients_id = I.id AND
Rel.recipe_id=R.id
INTERSECT
SELECT R.name
FROM Recipe R, Ingredients I, Relationship Rel
WHERE I.ingredients_name = 'Mayo' AND Rel.ingredients_id = I.id AND
Rel.recipe_id=R.id
这样做的目的是找到“鸡肉”是一种成分的所有食谱,并将其与所有“Mayo”成分的配方相交。这为您提供了食谱,其中“鸡肉”和“梅奥”是两种给定食谱的成分。
第二个想法,MySQL没有INTERSECT关键字。在这种情况下,试试这个:
SELECT DISTINCT R.name FROM Recipe R
INNER JOIN (SELECT R.name
FROM Recipe R, Ingredients I, Relationship Rel
WHERE I.ingredients_name = 'Chicken' AND Rel.ingredients_id = I.id AND
Rel.recipe_id=R.id) as recipeA
INNER JOIN (SELECT R.name
FROM Recipe R, Ingredients I, Relationship Rel
WHERE I.ingredients_name = 'Mayo' AND Rel.ingredients_id = I.id AND
Rel.recipe_id=R.id) as recipeB
答案 1 :(得分:2)
类似于我对第一个问题的回答(现已更正) - 这应该返回包含所有指定成分的所有食谱,但还需要其他成分:< / p>
SELECT r.* from recipe r
INNER JOIN relationship ri on r.id=ri.recipe_id
INNER JOIN ingredients i on i.id=ri.ingredients_id
GROUP BY r.id
HAVING COUNT(DISTINCT i.ingredients_name)>2 AND
COUNT(DISTINCT case when i.ingredients_name IN ('chicken','mayonnaise')
then i.ingredients_name end)=2
答案 2 :(得分:1)
我认为simchona可能会很好,但你显然必须在一个循环中生成代码,为每个成分制作一个select子句。
有些人解决类似问题的另一种方法是将一个列聚合成一个字符串并对其进行测试。我认为在性能和可维护性方面,两种方式都有利有弊。如果要查看此方法,决定如何连接字符串的好地方是http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/
另一个选择是创建一个存储过程并在循环中使用一些TSQL来创建匹配项列表...绝对是我通常会选择的最后一个选项但是根据你需要的性能有多好,这可能是一个可行的途径。
答案 3 :(得分:0)
我认为以下查询将满足要求:
SELECT r.recipe_name from recipe r
INNER JOIN relationship ri on r.id=ri.recipe_id
INNER JOIN ingredients i on i.id=ri.ingredients_id
where i.ingredients_name IN ('chicken','mayonnaise')
GROUP BY r.recipe_name
HAVING COUNT(i.ingredients_name) > 1