Undgå NOT IN
som pesten hvis
SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1
nogensinde kunne indeholde NULL. Brug i stedet IKKE FINDER eller Venstre Joins
brug eksplicitte joinforbindelser, ikke sammenføjninger i 1980'er-stil ved hjælp af WHERE
klausul
For at illustrere elendigheden ved NOT IN:
SQL IKKE I () fare
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);
** 3 rækker, som forventet **
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);
ingen rækker, hva?
Det er åbenbart "forkert". Det opstår fra SQL's brug af logik med tre værdier, drevet af eksistensen af NULL, en ikke-værdi, der indikerer manglende (eller Ukendt) information. Med NOT IN, Chunk2 er det oversat som dette:
status NOT IN ('married', 'divorced', 'widowed', NULL)
Dette svarer til:
NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
Udtrykket "status=NULL" evalueres til UNKNOWN, og ifølge reglerne for logik med tre værdier evalueres NOT UNKNOWN også til UNKNOWN. Som følge heraf filtreres alle rækker fra, og forespørgslen returnerer et tomt sæt.
Mulige løsninger omfatter:
select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null
eller brug not exists