Pembaruan:
Artikel di blog saya ini menjelaskan perbedaan antara metode secara lebih rinci:
NOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:SQL ServerNOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:PostgreSQLNOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:OracleNOT INvs.NOT EXISTSvs.LEFT JOIN / IS NULL:MySQL
Ada tiga cara untuk melakukan kueri seperti itu:
-
LEFT JOIN / IS NULL:SELECT * FROM common LEFT JOIN table1 t1 ON t1.common_id = common.common_id WHERE t1.common_id IS NULL -
NOT EXISTS:SELECT * FROM common WHERE NOT EXISTS ( SELECT NULL FROM table1 t1 WHERE t1.common_id = common.common_id ) -
NOT IN:SELECT * FROM common WHERE common_id NOT IN ( SELECT common_id FROM table1 t1 )
Ketika table1.common_id tidak dapat dibatalkan, semua kueri ini secara semantik sama.
Jika nullable, NOT IN berbeda, karena IN (dan, oleh karena itu, NOT IN ) kembalikan NULL ketika suatu nilai tidak cocok dengan apa pun dalam daftar yang berisi NULL .
Ini mungkin membingungkan tetapi mungkin menjadi lebih jelas jika kita mengingat sintaks alternatif untuk ini:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
Hasil dari kondisi ini adalah produk boolean dari semua perbandingan dalam daftar. Tentu saja, satu NULL nilai menghasilkan NULL hasil yang membuat seluruh hasil NULL juga.
Kami tidak pernah bisa mengatakan dengan pasti bahwa common_id tidak sama dengan apa pun dari daftar ini, karena setidaknya salah satu nilainya adalah NULL .
Misalkan kita memiliki data ini:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL dan NOT EXISTS akan mengembalikan 3 , NOT IN akan mengembalikan tidak ada (karena akan selalu dievaluasi menjadi FALSE atau NULL ).
Di MySQL , jika pada kolom yang tidak dapat dibatalkan, LEFT JOIN / IS NULL dan NOT IN sedikit (beberapa persen) lebih efisien daripada NOT EXISTS . Jika kolom nullable, NOT EXISTS adalah yang paling efisien (sekali lagi, tidak banyak).
Di Oracle , ketiga kueri menghasilkan paket yang sama (sebuah ANTI JOIN ).
Di SQL Server , NOT IN / NOT EXISTS lebih efisien, karena LEFT JOIN / IS NULL tidak dapat dioptimalkan ke ANTI JOIN oleh pengoptimalnya.
Di PostgreSQL , LEFT JOIN / IS NULL dan NOT EXISTS lebih efisien daripada NOT IN , karena dioptimalkan ke Anti Join , sedangkan NOT IN menggunakan hashed subplan (atau bahkan subplan biasa jika subquery terlalu besar untuk di-hash)