让我假装我有一个大的食谱数据库。食谱表每个都有一个唯一的ID和一个成分表,有很多这样的集合:
ID | RECIPE | INGREDIENT
-------------------------------
1 | recipe_a | ingredient_a
2 | recipe_a | ingredient_b
3 | recipe_a | ingredient_c
4 | recipe_b | ingredient_a
5 | recipe_b | ingredient_d
6 | recipe_b | ingredient_e
用户可以搜索他们希望在食谱中看到的成分和他们没有看到的成分。当用户使用ingredient_a和ingredient_b而不是ingredient_d搜索配方时,所需查询应该能够生成recipe_a。
如何在一个查询中更好地做到这一点?
我尝试了相当天真的版本:
SELECT distinct recipe
from ingredients
where ingredient in (ingredient_a, ingredient_b)
and ingredient not in (ingredient_d)
这个obv失败了,因为它仍然会导致recipe_a和recipe_b,它应该这样做,因为第1行和第2行匹配recipe_a,第4行匹配recipe_b。
答案 0 :(得分:2)
Select Distinct ...
From Recipes As R
Where R.ingredient in(ingredient_a, ingredient_b...)
And Not Exists(
Select 1
From Recipes As R2
Where R2.Recipe = R.Recipe
And R2.Ingredient In(ingredient_d)
)
正如Jeffrey L Whitledge所提到的,上述查询将返回在所需列表中具有至少一个成分的任何配方,而在不需要的列表中没有。但是,如果您想要返回包含所需所有所需列表中的成分的配方,而不想在不需要的列表中找到所有
的配方。Select Distinct ...
From Recipes As R
Where Exists (
Select 1
From Recipes As R2
Where R2.Recipe = R.Recipe
And R2.ingredient in(ingredient_a, ingredient_b...)
Having Count(*) = @CountOfPassedIngredients
)
And Not Exists(
Select 1
From Recipes As R2
Where R2.Recipe = R.Recipe
And R2.Ingredient In(ingredient_d)
)
在这种情况下,您需要先确定所需成分的数量。