在 SQL 中,IN
語句和(hé) EXISTS
語句經常可(kě)以實現(xiàn)相(xiàng)✘±同的(de)查詢邏輯,但(dàn)執行(xíng)方式不(bù)同₩✔÷γ。IN
通(tōng)常用(yòng)于判斷某個(gè)值是(shì)否在★→♥&子(zǐ)查詢返回的(de)結果集中,而 EXISTS
則用(yòng)于判斷子(zǐ)查詢是(shì)否返回至少∞↓(shǎo)一(yī)條記錄(存在性判斷)。
下(xià)面通(tōng)過具體(tǐ)例子(zǐ)說(shuō)明(mín"↔£↓g)如(rú)何将 IN
語句用(yòng) EXISTS
語句替代。
場(chǎng)景說(shuō)明(míng)
假設有(yǒu)兩張表:
Orders
(訂單表):包含order_id
(訂單 ID)、user_id
(用(yòng)戶 ID)等字段。Users
(用(yòng)戶表):包含user_id
(用(yòng)戶 ID)、country
(國(guó)家(jiā))等字段。
需求:查詢所有(yǒu)「來(lái)自(zì)中國(guó)的(de)用(yò™∞&♣ng)戶」的(de)訂單信息。
用(yòng) IN
語句實現(xiàn)
sql
SELECT * FROM Orders o WHERE o.use®'r_id IN ( SELECT u.user_id FROM Us÷×φers u WHERE u.country = '中國(guó)' -- π←♦子(zǐ)查詢返回所有(yǒu)中國(guó)用(yòng)戶的(de)ID );♣λδ
邏輯:先通(tōng)過子(zǐ)查詢獲取所有(yǒu)中國(guó)用(yòng↔α÷©)戶的(de) user_id
,再判斷訂單表的(de) user_id
是(shì)否在這(zhè)個(gè)集合中。
用(yòng) EXISTS
語句實現(xiàn)(等價效果)
sql
SELECT * FROM Orders o WHERE EXISTS (₩¥ SELECT * -- EXISTS 隻關心是±λ(shì)否有(yǒu)記錄,SELECT 後的(de)內(&€nèi)容無意義 FROM Users u WHERE u.cou☆♦ntry = '中國(guó)' -- 條件(jiàn)1:用(yòng)戶來(↑€₩lái)自(zì)中國(guó) AND u.user_id = o.user_id ₹¶ -- 條件(jiàn)2:用(yòng)戶ID與當前訂單的(de)用¥¥'(yòng)戶ID匹配 );
邏輯:對(duì)于訂單表的(de)每一(yī)行(xíng)記錄(o
),檢查是(shì)否存在一(yī)條用(yòng)戶表記錄(u
),既滿足 “來(lái)自(zì)中國(guó)”,又(§♦≠yòu)滿足 “用(yòng)戶 ID 與當前訂單的(de)'♣用(yòng)戶 ID 相(xiàng)同”。如(rú)果存在,則保留該訂單記錄。
兩者的(de)核心等價性
IN
是(shì) “值在集合中”:o.user_id
是(shì)否在子(zǐ)查詢返回的(de)user_id
集合中。EXISTS
是(shì) “存在匹配記錄”:是(shì)否存在一♣♦♠(yī)條用(yòng)戶記錄,既符合子(zǐ)查詢條件(jiàn)(中國φ×<(guó)),又(yòu)與當前訂單關聯(user_id
相(xiàng)等)。
兩種寫法最終會(huì)篩選出完全相(xiàng)同的(de)訂單記∑≤✘錄。
擴展:多(duō)值匹配的(de) IN
轉 EXISTS
如(rú)果 IN
子(zǐ)查詢返回多(duō)列(如(rú) (a, b)
),EXISTS
同樣可(kě)以替代:
IN
寫法:
sql
SELECT * FROM TableA a WHERE (a.x, a.y) IN ( ÷¶ SELECT b.x, b.y FROM TableB b WHERE b∞↑β¶.status = 1 );

EXISTS
寫法:
sql
SELECT * FROM TableA a WHERE EXISTS ( SELEC↕>✘T * FROM TableB b WHE≠↓RE b.status = 1 AND b.x = a.x -- 多(du♣↑♦ō)字段匹配 AND b.y = a.y );

總結
EXISTS
替代 IN
的(de)核心思路(lù)是(shì):
将 IN
子(zǐ)查詢的(de) “值集合判斷”,轉化(huà)σλ為(wèi) “是(shì)否存在一(yī)條與主查詢當前行(xíα₽ng)匹配且滿足條件(jiàn)的(de)子(zǐ)查詢記錄”,通(tōn×π♠✘g)過 主表與子(zǐ)表的(de)字段關聯(如(rú) u.user_id = o.user_id
)實現(xiàn)等價過濾。