Encuentra ID de una lista que no existe en una tabla


19

Digamos que tengo el siguiente esquema y datos:

create table images(
  id int not null
);

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

Quiero realizar una consulta como:

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

Pero esto no funciona. El caso anterior debería volver 5, ya que no existe en los registros de la tabla.

Respuestas:


23

Puede usar una combinación externa contra una valueslista (similar a la respuesta de Martin mencionada anteriormente):

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 existsjunto con el constructor de fila:

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

Si lo desea, también puede poner la valuescláusula en un CTE para que la consulta final sea más fácil de leer:

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

Una forma de hacerlo sería usar VALUESpara crear una expresión de tabla con los identificadores para verificar y EXCEPTencontrar los que faltan.

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

6

Mientras usa EXCEPTcomo @Martin provisto , recuerde hacerlo EXCEPTALL, a menos que quiera pagar un poco más por intentar doblar duplicados.

Por cierto, una VALUESexpresión puede sostenerse por sí misma:

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

Pero obtienes nombres de columna predeterminados de esta manera.

Para una larga lista de valores, puede ser más conveniente proporcionarlo como una matriz y unnest. Sintaxis más corta:

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

Hay un par de técnicas básicas para la tarea:


0

Solo usa una segunda mesa y únete a ellos.

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
Si está ejecutando una selección simple y está creando una tabla solo para esto, puede que no sea la mejor solución.
Patrick D'appollonio
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.