sql >> Base de Datos >  >> RDS >> PostgreSQL

Seleccionar filas que no están presentes en otra tabla

Existen básicamente 4 técnicas para esta tarea, todas ellas SQL estándar.

NOT EXISTS

A menudo más rápido en Postgres.

SELECT ip 
FROM   login_log l 
WHERE  NOT EXISTS (
   SELECT  -- SELECT list mostly irrelevant; can just be empty in Postgres
   FROM   ip_location
   WHERE  ip = l.ip
   );

Considere también:

  • ¿Qué es más fácil de leer en las subconsultas EXISTS?

LEFT JOIN / IS NULL

A veces esto es lo más rápido. A menudo, el más corto. A menudo da como resultado el mismo plan de consulta que NOT EXISTS .

SELECT l.ip 
FROM   login_log l 
LEFT   JOIN ip_location i USING (ip)  -- short for: ON i.ip = l.ip
WHERE  i.ip IS NULL;

EXCEPT

Corto. No se integra tan fácilmente en consultas más complejas.

SELECT ip 
FROM   login_log

EXCEPT ALL  -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM   ip_location;

Tenga en cuenta que (según la documentación):

los duplicados se eliminan a menos que EXCEPT ALL se utiliza.

Por lo general, querrá el ALL palabra clave. Si no le importa, utilícelo de todos modos porque hace que la consulta sea más rápida .

NOT IN

Solo bueno sin NULL valores o si sabe manejar NULL adecuadamente. Yo no usarlo para este propósito. Además, el rendimiento puede deteriorarse con tablas más grandes.

SELECT ip 
FROM   login_log
WHERE  ip NOT IN (
   SELECT DISTINCT ip  -- DISTINCT is optional
   FROM   ip_location
   );

NOT IN lleva una "trampa" para NULL valores a cada lado:

  • Encuentre registros donde no existe unión

Pregunta similar en dba.SE dirigida a MySQL:

  • Seleccione filas donde el valor de la segunda columna no esté presente en la primera columna