Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL “NOT IN” заявка 3 таблици

Избягвайте 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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Управление на потребителски акаунт, роли, разрешения, удостоверяване PHP и MySQL - част 2

  2. Как да проверите размера на базата данни MySQL в Linux

  3. SYSDATE() срещу NOW() в MySQL:Каква е разликата?

  4. MySQL REPLACE() – Заменете всички екземпляри на подниз с друг низ

  5. Използвайте mysqldump за архивиране на MySQL или MariaDB