Rumah >pangkalan data >tutorial mysql >Mengapa MySQL 'NOT IN' Gagal dengan Tiga Jadual dan NULL, dan Apakah Alternatif yang Lebih Baik?
Apabila bekerja dengan tiga jadual, menggunakan operator "NOT IN" dalam pertanyaan boleh menjadi masalah, terutamanya apabila berurusan dengan nilai NULL. Artikel ini menunjukkan risiko yang berkaitan dengan penggunaan "TIDAK MASUK" dan mencadangkan penyelesaian alternatif.
Pertanyaan yang disediakan bertujuan untuk membandingkan dua jadual, Gred dan Penilaian, mengenal pasti rekod dalam Gred yang tidak terdapat dalam Penilaian. Walau bagaimanapun, apabila nama yang ditentukan ("JOHN") tidak wujud dalam Penilaian, pertanyaan gagal mengembalikan sebarang output.
Untuk menangani isu ini , elakkan menggunakan "TIDAK MASUK" jika subkueri yang digunakan untuk menapis data mungkin mengandungi nilai NULL. Sebaliknya, pertimbangkan untuk menggunakan "TIDAK WUJUD" atau gabungan kiri.
Mari kita jelaskan potensi bahaya menggunakan "TIDAK ADA":
Buat mStatus dan jadual orang dengan data sampel:
create table mStatus ( id int auto_increment primary key, status varchar(10) not null ); insert mStatus (status) values ('single'),('married'),('divorced'),('widow'); create table people ( id int auto_increment primary key, fullName varchar(100) not null, status varchar(10) null );
Chunk1:
truncate table people; insert people (fullName,`status`) values ('John Henry','single'); select * from mstatus where `status` not in (select status from people);
Output Jangkaan: 3 baris
Chunk2:
truncate table people; insert people (fullName,`status`) values ('John Henry','single'),('Kim Billings',null); select * from mstatus where status not in (select status from people);
Output Tidak Dijangka: 0 baris
Chunk kedua secara tidak dijangka tidak mengembalikan baris kerana logik tiga nilai SQL. Apabila subkueri termasuk nilai NULL, ungkapan "TIDAK MASUK" mungkin dinilai kepada TIDAK DIKETAHUI, menyebabkan semua baris ditapis keluar.
Untuk membetulkan perkara ini isu, gunakan "LEFT JOIN" atau "NOT EXISTS":
select s.status from mstatus s left join people p on p.status=s.status where p.status is null
select s.status from mstatus s where not exists (select 1 from people where people.status=s.status)
Penyelesaian alternatif ini mengendalikan nilai NULL dengan betul dan memberikan output yang diingini.
Atas ialah kandungan terperinci Mengapa MySQL 'NOT IN' Gagal dengan Tiga Jadual dan NULL, dan Apakah Alternatif yang Lebih Baik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!