从列表中查找表中不存在的 ID

Pat*_*nio 33 postgresql if-not-exists

假设我有以下架构和数据:

create table images(
  id int not null
);

insert into images values(1), (2), (3), (4), (6), (8);
Run Code Online (Sandbox Code Playgroud)

我想执行如下查询:

select id from images where id not exists in(4, 5, 6);
Run Code Online (Sandbox Code Playgroud)

但这不起作用。上面的情况应该返回5,因为它不存在于表记录中。

a_h*_*ame 45

您可以对values列表使用外连接(类似于上面提到的 Martin 的回答):

select t.id
from (
  values (4),(5),(6) 
) as t(id)
  left join images i on i.id = t.id
where i.id is null;
Run Code Online (Sandbox Code Playgroud)

not exists与行构造函数一起使用:

select *
from ( 
   values (4),(5),(6)
) as v(id)
where not exists (select *
                  from images i
                  where i.id = v.id);
Run Code Online (Sandbox Code Playgroud)

如果您愿意,还可以将values子句放入 CTE 以使最终查询更易于阅读:

with v (id) as (
 values (4),(5),(6)
)
select v.id
from v
  left join images i on i.id = v.id
where i.id is null;
Run Code Online (Sandbox Code Playgroud)


Mar*_*ith 15

一种方法是使用VALUES创建一个带有 id 的表表达式来检查和EXCEPT查找缺失的。

SELECT id
FROM (VALUES(4),(5),(6)) V(id)
EXCEPT
SELECT id 
FROM images;
Run Code Online (Sandbox Code Playgroud)


Erw*_*ter 13

在使用EXCEPT@Martin 提供的那样时,请记住制作它EXCEPTALL,除非您想为尝试折叠重复项支付一点额外费用。

顺便说一句,一个VALUES表达式可以独立存在:

VALUES (4),(5),(6)
EXCEPT ALL
SELECT id FROM images;
Run Code Online (Sandbox Code Playgroud)

但是您可以通过这种方式获得默认列名。

对于一长串值,将其作为数组和 unnest 提供可能更方便。更短的语法:

SELECT * FROM unnest('{4,5,6}'::int[]) id
EXCEPT ALL
SELECT id FROM images;
Run Code Online (Sandbox Code Playgroud)

该任务有几种基本技术: