次のスキーマとデータがあるとします。
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
は、テーブルレコードに存在しないため、返されるはずです。
回答:
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
いる@Martinのように使用している間は、重複を折り返そ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;
このタスクには基本的なテクニックがいくつかあります。
2番目のテーブルを使用して結合するだけです。
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