Pada dasarnya ada 4 teknik untuk tugas ini, semuanya SQL standar.
NOT EXISTS
Seringkali tercepat di 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
);
Pertimbangkan juga:
- Apa yang lebih mudah dibaca di subkueri EXISTS?
LEFT JOIN / IS NULL
Terkadang ini yang tercepat. Seringkali terpendek. Sering kali menghasilkan paket kueri yang sama dengan 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
Pendek. Tidak mudah diintegrasikan dalam kueri yang lebih kompleks.
SELECT ip
FROM login_log
EXCEPT ALL -- "ALL" keeps duplicates and makes it faster
SELECT ip
FROM ip_location;
Perhatikan bahwa (per dokumentasi):
duplikat dihilangkan kecuali
EXCEPT ALLdigunakan.
Biasanya, Anda akan menginginkan ALL kata kunci. Jika Anda tidak peduli, tetap gunakan karena membuat kueri lebih cepat .
NOT IN
Hanya bagus tanpa NULL nilai atau jika Anda tahu menangani NULL dengan baik. Saya akan tidak menggunakannya untuk tujuan ini. Selain itu, performa dapat menurun dengan tabel yang lebih besar.
SELECT ip
FROM login_log
WHERE ip NOT IN (
SELECT DISTINCT ip -- DISTINCT is optional
FROM ip_location
);
NOT IN membawa "perangkap" untuk NULL nilai di kedua sisi:
- Temukan rekaman yang tidak ada gabungannya
Pertanyaan serupa di dba.SE yang ditargetkan di MySQL:
- Pilih baris yang nilai kolom kedua tidak ada di kolom pertama