Postgresql 选择没有任何一组值的所有行

Postgresql selecting all rows which don't have any of a set of values

我有一个 table 叫餐。膳食有很多成分(例如土豆泥、西兰花、牛排),每个成分 has_many 过敏原。

我想要 select 不含任何给定过敏原列表的餐点。

如果我加入这三个 table,并且 allergen_id 不在(...过敏原 ID 列表)中,那么 return 如果有任何餐点不在要排除的过敏原列表中的过敏原,这是不正确的:

select * from meals m 
join components c on c.meal_id=c.id 
join allergens a on a.component_id=c.id
where a.id not in (1,2,3,4)

如果一顿饭含有过敏原 1、5 和 7,它仍会从上述查询中 return 得到。我怎么说“return 我所有的饭菜都不含以下任何过敏原”

更新 澄清示例。

假设我吃了一顿由土豆泥、豌豆和馅饼组成的饭菜。土豆泥里有奶制品,馅饼里有麸质。然后我吃了一顿含有肉类过敏原的牛排餐(对素食者不利)。

土豆泥、豌豆、馅饼 -> 乳制品、麸质

牛排、薯条 -> 肉类

我想要 select 不含任何乳制品的一餐或多餐。结果应该只有牛排/薯条餐。

如果我加入他们:

select * from meals m 
join components c on c.meal_id=c.id 
join allergens a on a.component_id=c.id

这将为我列出每种过敏原。因此,如果我添加 where 子句:

select * from meals m 
join components c on c.meal_id=c.id 
join allergens a on a.component_id=c.id
where a.id not in (2)

面筋会有一排,所以不会排除土豆泥/豌豆/馅饼餐。我如何排除它?

NOT EXISTS(...) 完全符合您的要求。

你自己的文字I want to select the meal(s) which doesn't have any of a given list of allergens.几乎可以直接翻译成SQL:


 -- How do I say:
 -- Return me all meals
select * from meals m
where not exists ( --  which doesn't have 
        select * 
        from  components c  -- any of the following allergens
        join allergens a on a.component_id = c.id AND a.id in (1,2,3,4)
        where c.meal_id = m.id
        );