PostgreSQL选择行,其中不存在与值X或Y相关的记录

问题描述

我有3张桌子:

Table        columns
---------------------
items        id,name
variations   id,item_id
images       id,variation_id,type

image具有variation,而variation具有item

我想找到没有{em> type 4或5 items的{​​{1}}(类型是0..5的任何整数,不能是 null )

下面的查询有效,但是它使用了 UNION 查询 带有 NOT IN 约束,我认为效率不高-问题是 因此,编写此查询的更有效方法是什么。

images

解决方

基于戈登斯的答案,以下最终解决方案是:

SELECT disTINCT i.id,i.name 
FROM items i 
INNER JOIN variations v 
  ON v.item_id = i.id 
INNER JOIN images vi 
  ON vi.variation_id = v.id 
WHERE i.id NOT IN (SELECT i.id FROM items i 
                  INNER JOIN variations v 
                    ON v.item_id = i.id 
                  INNER JOIN images vi 
                    ON vi.variation_id = v.id 
                  WHERE vi.type = 4
                  UNION
                  SELECT i.id FROM items i 
                  INNER JOIN variations v 
                    ON v.item_id = i.id 
                  INNER JOIN images vi 
                    ON vi.variation_id = v.id 
                  WHERE vi.type = 5)

解决方法

我想查找没有图像类型为4或5的物品

根据您的描述,听起来像not exists

select i.*
from items i
where not exists (select 1
                  from variations v join
                       images im
                       on v.image_id = im.id
                  where v.item_id = i.item_id and i.type in (4,5)
                 );
,

使用聚合方法替代戈登答案的方法:

SELECT DISTINCT
    i.id,i.name 
FROM items i 
INNER JOIN variations v 
    ON v.item_id = i.id 
INNER JOIN images vi 
    ON vi.variation_id = v.id
GROUP BY
    i.id
HAVING
    COUNT(*) FILTER (WHERE vi.type IN (4,5)) = 0;

请注意,以上假设iditems表中的主键列。如果没有,那么也许我们应该改用GROUP BY i.id,i.name