Hindari NOT IN
seperti wabah jika
SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1
bisa berisi NULL. Sebagai gantinya, gunakan NOT EXISTS atau Left Joins
gunakan gabungan eksplisit, bukan gabungan gaya 1980-an menggunakan WHERE
klausa
Untuk mengilustrasikan penderitaan NOT IN:
SQL TIDAK DI () bahaya
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
);
Potongan1:
truncate table people;
insert people (fullName,`status`) values ('John Henry','single');
select * from mstatus where `status` not in (select status from people);
** 3 baris, seperti yang diharapkan **
Potongan2:
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);
tidak ada baris, ya?
Jelas ini 'salah'. Ini muncul dari penggunaan logika tiga nilai SQL, didorong oleh keberadaan NULL, non-nilai yang menunjukkan informasi yang hilang (atau TIDAK DIKETAHUI). Dengan NOT IN, Chunk2 diterjemahkan seperti ini:
status NOT IN ('married', 'divorced', 'widowed', NULL)
Ini setara dengan:
NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
Ekspresi "status=NULL" dievaluasi menjadi UNKNOWN dan, menurut aturan logika tiga nilai,NOT UNKNOWN juga dievaluasi menjadi UNKNOWN. Akibatnya, semua baris difilter dan kueri mengembalikan set kosong.
Solusi yang memungkinkan meliputi:
select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null
atau gunakan not exists