如果只满足多个子句,如何返回一行

时间:2013-05-08 18:37:47

标签: sql ms-access

我正在申请分发液体。这是DB的组织

CANISTER:

  • canister_id {PK}
  • ingredient_id {FK}

成分:

  • ingredient_id {PK}
  • ingredient_name

饮料:

  • drink_id {PK}
  • drink_name

INGREDIENTINSTANCE:

  • INSTANCE_ID {PK}
  • drink_id {FK}
  • ingredient_id {FK}
  • 金额

每种饮料都含有多种成分(保存在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,我希望它出现在结果中,但如果罐中只有一种或零成分,则不希望它出现在结果中。

我确信这是明显的,但我想不出怎么做。

2 个答案:

答案 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;

这是为了获取饮品名称加入IngredientInstanceDrink。然后它正在对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