Er zijn in principe 4 technieken voor deze taak, allemaal standaard SQL.
NOT EXISTS
Vaak het snelst in 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
);
Overweeg ook:
- Wat is gemakkelijker te lezen in EXISTS-subquery's?
LEFT JOIN / IS NULL
Soms is dit het snelst. Vaak het kortst. Resulteert vaak in hetzelfde zoekplan als 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. Niet zo gemakkelijk te integreren in complexere zoekopdrachten.
SELECT ip
FROM login_log
EXCEPT ALL -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM ip_location;
Merk op dat (volgens documentatie):
duplicaten worden verwijderd tenzij
EXCEPT ALL
wordt gebruikt.
Meestal wilt u de ALL
trefwoord. Als het je niet kan schelen, gebruik het dan nog steeds, want het maakt de zoekopdracht sneller .
NOT IN
Alleen goed zonder NULL
waarden of als u weet hoe u NULL
. moet verwerken op de juiste manier. Ik zou niet gebruik het voor dit doel. Ook kunnen de prestaties verslechteren bij grotere tafels.
SELECT ip
FROM login_log
WHERE ip NOT IN (
SELECT DISTINCT ip -- DISTINCT is optional
FROM ip_location
);
NOT IN
draagt een "val" voor NULL
waarden aan beide kanten:
- Records zoeken waar geen lidmaatschap bestaat
Soortgelijke vraag over dba.SE gericht op MySQL:
- Selecteer rijen waar de waarde van de tweede kolom niet aanwezig is in de eerste kolom