Der er grundlæggende 4 teknikker til denne opgave, alle standard SQL.
NOT EXISTS
Ofte hurtigst i 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
);
Overvej også:
- Hvad er nemmere at læse i EXISTS underforespørgsler?
LEFT JOIN / IS NULL
Nogle gange er dette hurtigst. Ofte kortest. Resulterer ofte i den samme forespørgselsplan som 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
Kort. Ikke så let integreret i mere komplekse forespørgsler.
SELECT ip
FROM login_log
EXCEPT ALL -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM ip_location;
Bemærk at (pr. dokumentation):
dubletter elimineres, medmindre EXCEPT ALL
bruges.
Typisk vil du have ALL
søgeord. Hvis du er ligeglad, så brug det stadig, fordi det gør forespørgslen hurtigere .
NOT IN
Kun god uden NULL
værdier eller hvis du ved at håndtere NULL
ordentligt. Jeg ville ikke bruge det til dette formål. Ydeevnen kan også forringes med større borde.
SELECT ip
FROM login_log
WHERE ip NOT IN (
SELECT DISTINCT ip -- DISTINCT is optional
FROM ip_location
);
NOT IN
bærer en "fælde" for NULL
værdier på begge sider:
- Find poster, hvor join ikke findes
Lignende spørgsmål på dba.SE rettet mod MySQL:
- Vælg rækker, hvor værdien af anden kolonne ikke er til stede i første kolonne