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 ALL
digunakan.
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