只用牛奶,鸡蛋,黄油,面粉,糖和盐可以制作多少食谱?

时间:2012-08-16 00:39:43

标签: sql postgresql

我有一个让我难过的SQL查询。基本上,我有一个Recipes表,其中包含(正如您无疑猜测的那样)许多食谱。我有一个Ingredients表,其中包含各种成分。我有一个RecipeIngredients表,它将食谱与其使用的成分联系起来。最后,我有一张PopularIngredients表(它实际上是一个视图,但是谁在乎?),其中包含了人们在厨房中最常用的成分:

CREATE Table Recipes
(
  RecipeId int4,
  Title varchar(100)
);

CREATE Table Ingredients
(
  IngredientId int4,
  Name varchar(100)
);

CREATE Table RecipeIngredients
(
  RecipeId int4,
  IngredientId int4,
  Amount int2
);

CREATE Table PopularIngredients
(
  IngredientId int4
);

我的目标是获取所有使用 热门成分的食谱清单。

可以找到带有示例数据的SQL小提琴here

我正在寻找的是一个将返回 Chicken Salad Pancakes 的查询。 Aligator Burgers 不会被退回,因为它使用的 aligator 不是一种受欢迎的成分。

我尝试了一些涉及子选择和ALL关键字的事情,但没有运气。我已经尝试了各种内部和外部连接,但只要至少有一种成分很受欢迎,配方行仍然会出现。任何帮助将不胜感激!

我使用的是Postgres 9.1。

3 个答案:

答案 0 :(得分:7)

这将获得所有不含在PopularIngredients表中的成分的食谱。

select * from Recipes r where not exists (
  select * from RecipeIngredients ri 
  left join PopularIngredients pi on pi.IngredientId=ri.IngredientId
  where ri.RecipeId=r.RecipeId and pi.IngredientId is null
)

答案 1 :(得分:5)

使用WHERE NOT EXISTS确保PopularIngredients视图中没有遗漏任何成分:

SELECT R.*
FROM Recipes R
WHERE NOT EXISTS (
    SELECT 1
    FROM RecipeIngredients RI
    LEFT JOIN PopularIngredients P ON P.IngredientId = RI.IngredientId
    WHERE RI.RecipeId = R.RecipeId AND P.IngredientId IS NULL
)

更新了您的SqlFiddle

答案 2 :(得分:2)

select r.Title
  from Recipes r
  join RecipeIngredients ri
    on r.RecipeId = ri.RecipeId
  left outer join PopularIngredients pi
    on ri.IngredientId = pi.IngredientId
 group by r.Title
 having count( case when pi.IngredientId is null then 1 end )=0

或几乎相同

select r.Title
  from Recipes r
  join RecipeIngredients ri
    on r.RecipeId = ri.RecipeId
  left outer join PopularIngredients pi
    on ri.IngredientId = pi.IngredientId
 group by r.Title
 having count(pi.IngredientId)=count(ri.IngredientId)