Klausa NOT IN
SQL dan Masalah Nilai NULL
Operator NOT IN
dalam SQL direka bentuk untuk memilih baris dengan nilai lajur tidak ditemui dalam set nilai yang ditentukan. Walau bagaimanapun, pengendali ini berkelakuan di luar jangkaan apabila set perbandingan mengandungi nilai NULL
. Artikel ini menerangkan tingkah laku ini dan menawarkan penyelesaian.
Masalahnya:
Pertimbangkan senario di mana anda cuba mencari produk dalam satu pangkalan data (Inventory
) yang tidak terdapat dalam pangkalan data subset (Subset
). Pendekatan biasa menggunakan NOT IN
mungkin kelihatan seperti ini:
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products]);</code>
Jika subkueri (SELECT foreignStockId FROM [Subset].[dbo].[Products]
) mengembalikan sebarang nilai NULL
, keseluruhan NOT IN
keadaan menjadi tidak tentu, menghasilkan set hasil kosong—walaupun terdapat nilai IdStock
dalam [Inventory].[dbo].[Stock]
iaitu tidak hadir dalam [Subset].[dbo].[Products]
.
Mengapa Ini Berlaku:
SQL menggunakan logik tiga nilai: TRUE
, FALSE
dan UNKNOWN
. Apabila membandingkan nilai dengan NULL
, hasilnya sentiasa UNKNOWN
. NOT IN
pada asasnya menyemak sama ada nilai adalah FALSE
untuk semua perbandingan. Memandangkan UNKNOWN
bukan FALSE
, mana-mana NULL
dalam set hasil subkueri menjadikan keseluruhan keadaan NOT IN
dinilai kepada set kosong.
Penyelesaian:
Untuk mengelakkan isu ini, gunakan salah satu kaedah berikut:
1. Kecualikan NULL secara eksplisit: Ubah suai subkueri untuk menapis nilai NULL
:
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE stock.IdStock NOT IN (SELECT foreignStockId FROM [Subset].[dbo].[Products] WHERE foreignStockId IS NOT NULL);</code>
2. Gunakan NOT EXISTS
: Pendekatan ini biasanya lebih disukai kerana kejelasan dan kecekapannya:
<code class="language-sql">SELECT stock.IdStock, stock.Descr FROM [Inventory].[dbo].[Stock] stock WHERE NOT EXISTS (SELECT * FROM [Subset].[dbo].[Products] p WHERE p.foreignStockId = stock.IdStock);</code>
Klausa NOT EXISTS
menyemak sama ada baris tiada wujud dalam subkueri yang sepadan dengan keadaan. Ia mengendalikan nilai NULL
dengan betul tanpa memerlukan pengecualian yang jelas.
Dengan memahami interaksi antara nilai NULL
dan operator NOT IN
, anda boleh menulis pertanyaan SQL yang lebih mantap dan boleh dipercayai. Alternatif NOT EXISTS
selalunya merupakan penyelesaian yang lebih bersih dan cekap apabila berhadapan dengan nilai NULL
yang berpotensi dalam set perbandingan.
Atas ialah kandungan terperinci Mengapa Pertanyaan SQL `NOT IN` Saya Tidak Mengembalikan Keputusan Apabila Nilai NULL Wujud dalam Subquery?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!