PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Seleziona le righe che non sono presenti in un'altra tabella

Esistono fondamentalmente 4 tecniche per questo compito, tutte SQL standard.

NOT EXISTS

Spesso il più veloce a 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
   );

Considera anche:

  • Cosa è più facile da leggere nelle sottoquery EXISTS?

LEFT JOIN / IS NULL

A volte questo è più veloce. Spesso il più corto. Spesso risulta nello stesso piano di query di 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

Breve. Non facilmente integrabile in query più complesse.

SELECT ip 
FROM   login_log

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

Nota che (per documentazione):

i duplicati vengono eliminati a meno che EXCEPT ALL viene utilizzato.

In genere, vorrai il ALL parola chiave. Se non ti interessa, usalo comunque perché rende la query più veloce .

NOT IN

Buono solo senza NULL valori o se sai come gestire NULL correttamente. Io non usalo per questo scopo. Inoltre, le prestazioni possono peggiorare con tabelle più grandi.

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

NOT IN porta una "trappola" per NULL valori su entrambi i lati:

  • Trova record in cui il join non esiste

Domanda simile su dba.SE mirata a MySQL:

  • Seleziona le righe in cui il valore della seconda colonna non è presente nella prima colonna