3

我正在开发一个分配液体的应用程序。这是数据库的组织

罐:

  • canister_id{PK}
  • 成分_id{FK}

成分:

  • 成分ID{PK}
  • 成分名称

喝:

  • Drink_id{PK}
  • 饮料名称

成分:

  • instance_id{PK}
  • drink_id{FK}
  • 成分_id{FK}
  • 数量

每种饮料都有多种成分(保存在成分实例表中),但只有 12 个罐。我正在尝试编写一个 SQL 命令,该命令将收集目前在罐中具有所有必需成分的所有饮料。

到目前为止,这就是我所拥有的。

SELECT DISTINCT Drink.drink_name
FROM Drink, ingredientInstance, Canister
WHERE (((ingredientInstance.drink_id)=[Drink].[drink_id])
AND ((ingredientInstance.ingredient_id) 
IN (select ingredient_id FROM Canister)));

然而,这将退回所有含有单一成分的饮料。我正在寻找的是一种方法,以确保对于成分实例中的每个相关成分,它当前都在罐中。

例如,假设drink1需要成分1和成分2 。如果罐中存在这两种成分 ID,我希望它出现在结果中,但如果罐中只有一种或零成分,则不会。

我确定这很明显,但我想不出该怎么做。

4

2 回答 2

2

这是集合内集合查询的示例。我主张为此使用带有having子句的聚合:

select drink.drinkname
from IngredientInstance ii join
     Drink d
     on ii.DrinkId = d.Drinkid left join
     Canister c
     on ii.IngredientId = c.INgredientId
group by drink.drinkname
having sum(iif(c.IngredientId is null, 1, 0)) = 0;

这是加入IngredientInstanceDrink只是为了得到饮料的名字。然后它正在left joinCanister桌子做一个。这样可以将饮料中的所有成分与罐中的匹配成分(如果有)一起保留。如果 缺少成分Canister,则它具有 NULL ingredientId

通过group by饮料看成分。最后一个having条款计算缺少成分的数量,并且只返回没有缺少成分的饮料。

于 2013-05-08T18:46:53.660 回答
1
select d.* from drink d inner join
(select i.drink_id, sum(case when c.canister_id is null 1 else 0 end) as fullcanister
from ingredientinstance i left join canister c on c.ingredient_id=i.ingredient_id 
group by i.drink_id) as id on id.drink_id=d.drink_id and id.fullcanister=0
于 2013-05-08T18:47:43.310 回答