Избягвайте NOT IN
като чумата, ако
SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1
може да съдържа NULL. Вместо това използвайте NOT EXISTS или Left Joins
използвайте изрични съединения, а не присъединявания в стил от 1980 г., като използвате WHERE
клауза
За да илюстрира мизерията на NOT IN:
SQL НЕ В () опасност
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
);
Част 1:
truncate table people;
insert people (fullName,`status`) values ('John Henry','single');
select * from mstatus where `status` not in (select status from people);
** 3 реда, както се очаква **
Част 2:
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);
без редове, а?
Очевидно това е "неправилно". Той възниква от използването от SQL на тризначна логика, задвижвана от съществуването на NULL, не-стойност, показваща липсваща (или НЕИЗВЕСТНА) информация. С NOT IN, Chunk2 се превежда по следния начин:
status NOT IN ('married', 'divorced', 'widowed', NULL)
Това е еквивалентно на:
NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)
Изразът "status=NULL" се оценява на UNKNOWN и, според правилата на тризначната логика, NOT UNKNOWN също се оценява на UNKNOWN. В резултат на това всички редове се филтрират и заявката връща празен набор.
Възможните решения включват:
select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null
или използвайте not exists