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