Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zapytanie MySQL „NIE W” 3 tabele

Unikaj NOT IN jak zaraza, jeśli

SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1

może kiedykolwiek zawierać NULL. Zamiast tego użyj opcji NOT EXISTS lub Left Joins

używaj jawnych złączeń, a nie złączeń w stylu lat 80., używając WHERE klauzula

Aby zilustrować niedolę NOT IN:

SQL NOT IN () niebezpieczeństwo

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
);

Fragment 1:

truncate table people;
insert people (fullName,`status`) values ('John Henry','single');
select * from mstatus where `status` not in (select status from people);

** 3 rzędy, zgodnie z oczekiwaniami **

Kawałek2:

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);

brak wierszy, co?

Oczywiście jest to „niepoprawne”. Wynika to z użycia przez SQL trójwartościowej logiki, napędzanej istnieniem NULL, nie będącej wartością wskazującą na brakujące (lub NIEZNANE) informacje. Z NOT IN, Chunk2 jest tłumaczony w ten sposób:

status NOT IN ('married', 'divorced', 'widowed', NULL)

Odpowiada to:

NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)

Wyrażenie „status=NULL” oceniane jest jako NIEZNANE i, zgodnie z regułami logiki trójwartościowej, NIEZNANE również obliczane jest jako NIEZNANE. W rezultacie wszystkie wiersze są odfiltrowywane, a zapytanie zwraca pusty zestaw.

Możliwe rozwiązania to:

select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null

lub użyj 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. Uzyskiwanie pierwszego dnia tygodnia w MySql za pomocą Week No

  2. mysqli lub PDO - jakie są plusy i minusy?

  3. Jak skopiować tabelę w MySQL

  4. odpowiednik generate_series() w MySQL

  5. Jak zwiększyć połączenia MySQL (max_connections)?