テーブルに存在しないリストから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は、テーブルレコードに存在しないため、返されるはずです。

回答:


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

それを行う1つの方法はVALUES、IDを使用してテーブル式を作成し、チェックしEXCEPTて不足しているものを見つけることです。

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

6

提供されEXCEPTいる@Martinのように使用している間は重複を折り返そ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

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

3
単純な選択を実行していて、これだけのためにテーブルを作成している場合、それは最良の解決策ではないかもしれません。
パトリックD'appollonio
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.