Trova gli ID da un elenco che non esiste in una tabella


19

Supponiamo di avere i seguenti schemi e dati:

create table images(
  id int not null
);

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

Voglio eseguire una query come:

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

Ma questo non funziona. Il caso precedente dovrebbe tornare 5, poiché non esiste nei record della tabella.

Risposte:


23

È possibile utilizzare un join esterno in un valueselenco (simile alla risposta di Martin menzionata sopra):

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;

o un not existsinsieme al costruttore della riga:

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

Se lo desideri, puoi anche inserire la valuesclausola in un CTE per facilitare la lettura della query finale:

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

Un modo per farlo sarebbe utilizzare VALUESper creare un'espressione di tabella con gli ID per verificare e EXCEPTtrovare quelli mancanti.

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

6

Mentre usi EXCEPTcome @Martin fornito , ricordati di farlo EXCEPTALL, a meno che tu non voglia pagare un piccolo extra per provare a piegare i duplicati.

A proposito, VALUESun'espressione può stare da sola:

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

Ma ottieni i nomi di colonna predefiniti in questo modo.

Per un lungo elenco di valori può essere più conveniente fornirlo come array e inutile. Sintassi più breve:

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

Esistono un paio di tecniche di base per l'attività:


0

Usa solo un secondo tavolo e unisciti a loro.

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
Se stai eseguendo una selezione semplice e stai creando una tabella solo per questo, potrebbe non essere la soluzione migliore.
Patrick D'appollonio,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.