2010-03-10 66 views
1

讓我們假裝我有一個大的配方數據庫。一個表食譜每一個唯一的ID和表一整很多套這樣的成分:SQL查詢需要找到不同的ID可能使用IN和NOT IN

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 。

回答

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) 
        ) 

作爲傑弗裏大號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) 
        ) 

在這種情況下,你需要有先確定的計所需的成分。

+0

除非我錯過了某些東西,否則這會讀取包含ANY的食譜,而不是所有所需的成分。 – 2010-03-10 22:28:05

+0

這是OP的問題。想要的結果是返回包含所有給定成分集合而不是所有不想要的成分的食譜,或者是否應該返回包含至少一種給定成分而沒有任何不想要的成分的食譜? – Thomas 2010-03-10 23:02:57

+0

這兩個版本都像魅力一樣工作,並會讓我添加這個,以便用戶可以選擇模式。不勝感激! – KMB 2010-03-11 20:40:39