Undvik NOT IN
som pesten om
SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1
någonsin kan innehålla NULL. Använd istället INTE FINNS eller Left Joins
använd explicita kopplingar, inte kopplingar i 1980-talsstil med WHERE
klausul
För att illustrera eländet med NOT IN:
SQL INTE I () fara
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 rader, som förväntat **
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);
inga rader, va?
Uppenbarligen är detta "felaktigt". Det härrör från SQLs användning av logik med tre värden, som drivs av förekomsten av NULL, ett icke-värde som indikerar saknad (eller OKÄND) information. Med NOT IN, Chunk2 översätts det så här:
status NOT IN ('married', 'divorced', 'widowed', NULL)
Detta motsvarar:
NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
Uttrycket "status=NULL" utvärderas till OKÄNT och, enligt reglerna för logik med tre värden, utvärderas NOT UNKÄNT också till OKÄNT. Som ett resultat filtreras alla rader bort och frågan returnerar en tom uppsättning.
Möjliga lösningar inkluderar:
select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null
eller använd not exists