Suchen Sie IDs aus einer Liste, die in einer Tabelle nicht vorhanden sind

19

Angenommen, ich habe das folgende Schema und die folgenden Daten:

create table images(
  id int not null
);

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

Ich möchte eine Abfrage durchführen wie:

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

Das geht aber nicht. Der obige Fall sollte zurückgegeben werden 5, da er in den Tabellendatensätzen nicht vorhanden ist.

Patrick D'appollonio
quelle

Antworten:

23

Sie können einen Outer Join für eine valuesListe verwenden (ähnlich wie bei der oben genannten Antwort von 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;

oder a not existszusammen mit dem Zeilenkonstruktor:

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

Wenn Sie möchten, können Sie die valuesKlausel auch in einen CTE einfügen, um die endgültige Abfrage besser lesbar zu machen:

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;
ein Pferd ohne Name
quelle
10

Eine Möglichkeit wäre VALUES, einen Tabellenausdruck mit den IDs zu erstellen EXCEPT, um die fehlenden zu überprüfen und zu finden.

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

Bei der Verwendung von EXCEPTwie @ Martin zur Verfügung gestellt , denken Sie daran , es zu machen EXCEPTALL, es sei denn , Sie versuchen , Duplikate zu falten , ein wenig mehr zu zahlen bereit ist .

Übrigens kann ein VALUESAusdruck für sich stehen:

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

Auf diese Weise erhalten Sie jedoch Standardspaltennamen.

Für eine lange Liste von Werten ist es möglicherweise praktischer, sie als Array und als unnest bereitzustellen. Kürzere Syntax:

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

Es gibt ein paar grundlegende Techniken für die Aufgabe:

Erwin Brandstetter
quelle
0

Benutze einfach einen zweiten Tisch und schließe dich ihnen an.

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
quelle
3
Wenn Sie eine einfache Auswahl ausführen und dafür eine Tabelle erstellen, ist dies möglicherweise nicht die beste Lösung.
Patrick D'appollonio