sql >> Databasteknik >  >> RDS >> Mysql

MySQL "NOT IN" fråga 3 tabeller

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



  1. Hur hittar man främmande nyckelberoenden i SQL Server?

  2. Rails 3, ActiveRecord, PostgreSQL - .uniq-kommandot fungerar inte?

  3. Skalär UDF Inlining i SQL Server 2019

  4. Vad är syftet med datareplikering?