Temukan ID dari daftar yang tidak ada dalam tabel

19

Katakanlah saya memiliki skema dan data berikut:

create table images(
  id int not null
);

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

Saya ingin melakukan kueri seperti:

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

Tetapi ini tidak berhasil. Kasus di atas harus kembali 5, karena tidak ada dalam catatan tabel.

Patrick D'appollonio
sumber

Jawaban:

23

Anda dapat menggunakan gabungan luar dengan valuesdaftar (mirip dengan jawaban Martin yang disebutkan di atas):

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;

atau not existsbersama dengan konstruktor baris:

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

Jika suka, Anda juga dapat memasukkan valuesklausa ke dalam CTE untuk membuat kueri akhir lebih mudah dibaca:

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;
seekor kuda tanpa nama
sumber
10

Salah satu cara melakukannya adalah menggunakan VALUESuntuk membuat ekspresi tabel dengan id untuk memeriksa danEXCEPT menemukan yang hilang.

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

Saat menggunakan EXCEPTseperti @Martin disediakan , ingatlah untuk membuatnya EXCEPTALL, kecuali jika Anda ingin membayar sedikit ekstra untuk mencoba melipat duplikat.

BTW, a VALUES ekspresi dapat berdiri sendiri:

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

Tetapi Anda mendapatkan nama kolom default dengan cara ini.

Untuk daftar nilai yang panjang , mungkin lebih mudah untuk menyediakannya sebagai array dan undest. Sintaks yang lebih pendek:

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

Ada beberapa teknik dasar untuk tugas ini:

Erwin Brandstetter
sumber
0

Cukup gunakan tabel kedua dan bergabunglah dengan mereka.

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
dfundako
sumber
3
Jika Anda mengeksekusi pilihan sederhana dan Anda membuat tabel hanya untuk ini, itu mungkin bukan solusi terbaik.
Patrick D'appollonio