web-dev-qa-db-fra.com

Rechercher des ID dans une liste qui n'existent pas dans une table

Disons que j'ai le schéma et les données suivants:

create table images(
  id int not null
);

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

Je souhaite effectuer une requête comme:

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

Mais ça ne marche pas. Le cas ci-dessus doit renvoyer 5, car il n'existe pas dans les enregistrements de la table.

21

Vous pouvez utiliser une jointure externe contre une liste values (similaire à la réponse de Martin mentionnée ci-dessus):

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;

ou un not exists avec le constructeur de ligne:

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

Si vous le souhaitez, vous pouvez également placer la clause values dans un CTE pour faciliter la lecture de la requête 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;
25

Une façon de le faire serait d'utiliser VALUES pour créer une expression de table avec les identifiants à vérifier et EXCEPT pour trouver le manquant ceux.

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

Lorsque vous utilisez EXCEPT comme @ Martin fourni , n'oubliez pas de le faire EXCEPTALL, sauf si vous voulez payer un petit supplément pour essayer de plier les doublons.

BTW, une expression VALUES peut se suffire à elle-même:

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

Mais vous obtenez les noms de colonnes par défaut de cette façon.

Pour une longue liste de valeurs, il peut être plus commode de la fournir sous forme de tableau et de ne pas lâcher. Syntaxe plus courte:

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

Il existe quelques techniques de base pour la tâche:

8
Erwin Brandstetter

Utilisez simplement une deuxième table et rejoignez-les.

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
0
dfundako