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


19

说我有以下架构和数据:

create table images(
  id int not null
);

insert into images values(1), (2), (3), (4), (6), (8);

我想执行如下查询:

select id from images where id not exists in(4, 5, 6);

但这是行不通的。上面的情况应该返回5,因为它在表记录中不存在。

Answers:


23

您可以对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;

not exists与行构造器一起使用:

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

如果愿意,还可以将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;

10

一种方法是使用VALUES创建具有ID的表表达式来检查并EXCEPT查找丢失的表达式。

SELECT id
FROM (VALUES(4),(5),(6)) V(id)
EXCEPT
SELECT id 
FROM images;

6

当使用EXCEPT@马丁提供,记得让EXCEPTALL,除非你想付出一点额外的努力折重复。

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

VALUES (4),(5),(6)
EXCEPT ALL
SELECT id FROM images;

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

对于一长串的值,将其提供为数组和嵌套即可更为方便。较短的语法:

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

该任务有两种基本技术:


0

只需使用第二张表并加入它们即可。

create table images1(
  id int not null
);

create table images2(
  id int not null
);

insert into images1 values(1), (2), (3), (4), (6), (8);

insert into images2 values (4), (5), (6);

SELECT i2.ID

FROM images2 i2

LEFT JOIN images1 i1
    ON i1.ID = i2.ID

WHERE i1.ID IS NULL

3
如果您正在执行一个简单的选择,而您正为此创建一个表,则它可能不是最佳解决方案。
Patrick D'appollonio
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.