说我有以下架构和数据:
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
,因为它在表记录中不存在。
说我有以下架构和数据:
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:
您可以对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;
当使用EXCEPT
像@马丁提供,记得让EXCEPT
ALL
,除非你想付出一点额外的努力折重复。
顺便说一句,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;
该任务有两种基本技术:
只需使用第二张表并加入它们即可。
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