首頁 >資料庫 >mysql教程 >為什麼 MySQL 的「NOT IN」會因為三個表和 NULL 而失敗,有哪些更好的替代方案?

為什麼 MySQL 的「NOT IN」會因為三個表和 NULL 而失敗,有哪些更好的替代方案?

DDD
DDD原創
2024-12-31 05:49:091027瀏覽

Why Does MySQL's

MySQL「NOT IN」查詢三個表格

處理三個表格時,在查詢中使用「NOT IN」運算符可能會出現問題,尤其是在處理NULL 值時。本文示範了與使用「NOT IN」相關的風險,並提出了替代解決方案。

問題

提供的查詢旨在比較兩個表,Grade 和評估,識別等級中未出現在評估中的記錄。但是,當計算中不存在指定的名稱(“JOHN”)時,查詢將無法傳回任何輸出。

解決方案

解決此問題,如果用於過濾資料的子查詢可能包含 NULL 值,請避免使用「NOT IN」。相反,請考慮使用“NOT EXISTS”或左連接。

讓我們說明使用「NOT IN」的潛在危險:

SQL “NOT IN”危險

建立mStatus 和people表格包含樣本資料:

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 行

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

Chunk2:

0 rows

第二個區塊意外地沒有回傳任何行,因為SQL的三值邏輯。當子查詢包含 NULL 值時,「NOT IN」表達式的計算結果可能為 UNKNOWN,從而導致所有行被過濾掉。

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

替代方案

select s.status
from mstatus s
where not exists (select 1 from people where people.status=s.status)

解決此問題問題,使用「LEFT JOIN」或「NOT EXISTS":

這些替代解決方案正確處理NULL 值並提供所需的輸出。

以上是為什麼 MySQL 的「NOT IN」會因為三個表和 NULL 而失敗,有哪些更好的替代方案?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn