基于 SQL 中的 EXISTS 運算符為我們提供了一種基于其他數據是否存在(或不存在)來(lái)檢索數據的簡(jiǎn)便方法。更具體地說(shuō),它是一個(gè)邏輯運算符,用于評估子查詢(xún)的結果,并返回一個(gè)布爾值,該值指示是否返回了行。盡管 IN 運算符可用于類(lèi)似的目的,但需要注意它們之間的一些差異。今天的博客將介紹如何使用 EXISTS 運算符的幾個(gè)示例,并提供一些指導,說(shuō)明何時(shí)應使用 EXISTS 而不是 IN。


EXISTS 在實(shí)踐中的應用


盡管 EXISTS 運算符可以在 SELECT、UPDATE、INSERT DELETE 語(yǔ)句中使用,但為了保持簡(jiǎn)單,我們將重點(diǎn)介紹 SELECT 查詢(xún)。因此,我們將使用的語(yǔ)法將非常類(lèi)似于以下形式:


 


我們將在 PostgreSQL 的幾個(gè)表上執行我們的查詢(xún)——比如客戶(hù)和賬戶(hù)表,這些表在銀行數據庫中很常見(jiàn)。下面是在 Navicat for PostgreSQL 網(wǎng)格視圖中顯示的這些表:



現在,我們可以使用以下查詢(xún)來(lái)查看所有具有與其 customer_id 相關(guān)聯(lián)的賬戶(hù)的客戶(hù):


 


以下是在 Navicat Premium 的查詢(xún)編輯器中執行上述查詢(xún)的結果:



使用 NOT EXISTS


相反地,在 EXISTS 運算符前加上 NOT 關(guān)鍵字會(huì )導致查詢(xún)只選擇子查詢(xún)中沒(méi)有匹配行的記錄。我們可以使用 NOT EXISTS 來(lái)檢索所有孤立的賬戶(hù),即沒(méi)有關(guān)聯(lián)客戶(hù)的賬戶(hù):


 


由于客戶(hù)表中沒(méi)有該 ID 的客戶(hù),所以它返回了客戶(hù) #4 的賬戶(hù)。



Joins 替換 EXISTS


使用 EXISTS 運算符的查詢(xún)可能執行起來(lái)有點(diǎn)慢,因為子查詢(xún)需要對外層查詢(xún)的每一行都執行一次。因此,你應該盡可能考慮使用連接。事實(shí)上,我們可以使用 LEFT JOIN 來(lái)重寫(xiě)上面的EXISTS 查詢(xún):


 

 


IN vs EXISTS 運算符


盡管 IN 運算符通常用于為列的某個(gè)值列表設置過(guò)濾器,但它也可以應用于子查詢(xún)的結果。以下是我們第一個(gè)查詢(xún)的等效查詢(xún),但這次使用的是 IN 而不是 EXISTS


 


請注意,我們只能選擇想要進(jìn)行比較的列,而不能選擇 SELECT *。不過(guò),IN 查詢(xún)會(huì )產(chǎn)生相同的結果:



由于這兩個(gè)操作符非常相似,數據庫開(kāi)發(fā)人員往往不確定應該使用哪一個(gè)。一般來(lái)說(shuō), 當你想根據特定值列表篩選行時(shí),應該使用 IN 操作符。當你想檢查子查詢(xún)中是否存在滿(mǎn)足某些條件的行時(shí),應該使用 EXISTS。