我正在申请分发液体。这是DB的组织
CANISTER:
成分:
饮料:
INGREDIENTINSTANCE:
每种饮料都含有多种成分(保存在ingredientInstance表中),但只有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)));
然而,这将返回所有饮料,甚至可以提供单一成分。我正在寻找的是一种方法来确保每个相关成分在ingredientInstance中,它目前在一个罐中。
例如,假设 drink1 需要 ingredient1 和 ingredient2 。如果罐中存在这两种成分ID,我希望它出现在结果中,但如果罐中只有一种或零成分,则不希望它出现在结果中。
我确信这是明显的,但我想不出怎么做。
答案 0 :(得分:2)
这是set-within-sets查询的示例。我主张使用带有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;
这是为了获取饮品名称加入IngredientInstance
和Drink
。然后它正在对left join
表执行Canister
。这样可以保留饮料中的所有成分以及罐中的匹配成分(如果有的话)。如果Canister
中缺少某种成分,则其{NULL}为ingredientId
。
group by
通过饮料观察成分。最终的having
条款计算缺失成分的数量,并且只返回没有缺少成分的饮料。
答案 1 :(得分: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