SQL中如何使用EXISTS替代IN

2022-02-09 16:57:27 字數 1321 閱讀 2699

我們在程式中一般在做sql優化的時候講究使用exists帶替代in的做法,理由是exists執行效率要比in高。

之前我一直挺懵懂的一件事情是如何使用exists來替換in呢,二者表示的意義又是什麼呢?今天就我個人理解記錄一下

in表示範圍,指某一字段在某一範圍之內,這個範圍一般使用子查詢來獲取,由此可知in子查詢返回的結果應該就是這個範圍集。

exists表示存在,指至少存在一處,這個條件由exists子查詢來完成,但是在這裡exists子查詢返回的結果卻不再是乙個結果集,而是乙個布林值(true或false),其實這個挺好理解的,exists就表示如果子查詢能查到值則返回true,則執行exists之前的語句。

舉個栗子

假如有乙個表user,它有兩個欄位id和name,我們要查詢名字中帶a的使用者資訊:

最簡單的sql:select * from user where name like '%a%';

使用in的sql:select u.* from user u where u.id in (select uu.id from user uu where uu.name like '%a%');

我們現在將使用in的sql修改為使用exists的sql該怎麼寫呢?

一開始我直接將u.id in 替換為exists,獲得如下語句 :

select u.* from user u where exists(select uu.id from user uu where uu.name like '%a%');

經過測試發現輸出結果錯誤,該語句將所有的使用者全部乙個不漏的查詢出來了,相信你也發現了問題,後來我對上述語句做了修改如下:

select u.* from user u where exists (select uu.id from user uu where uu.name like '%a%' and uu.id=u.id);

如你所見,只是在子查詢中新增了「and uu.id=u.id」,結果查詢結果正確。

那麼原因為何呢?

總結:exists子查詢可以看成是乙個獨立的查詢系統,只為了獲取真假邏輯值,exists子查詢與外查詢查詢的表是兩個完全獨立的毫無關係的表(當第二個表中的name中有包含a的姓名存在,那麼就執行在第乙個表中查詢所有使用者的操作),當我們在子查詢中新增了id關聯之後,exists子查詢與外查詢查詢的表就統一了,是二者組合組建的虛表,是同乙個表(這樣當子查詢查詢到虛表中當前行的uu.name中包含a時,則將虛表當前行中對應的u.id與u.name查詢到了)

所以一切的重點就在這個id關聯之上,新增id關聯,資料庫會先將兩張表通過id關聯組合成一張虛表,所有的查詢操作都在這張虛表上完成,操作的是同一張表,當然就不會出現之前的那種情況了!

SQL中EXISTS的使用

網上有一些關於exists 說明的例子,但都說的不是很詳細.比如對於著名的供貨商資料庫,查詢 找出 所有零件的 商的 商名,對於這個查詢,網上一些關於exists的說明文章都不能講清楚.我先解釋本文所用的資料庫例子,供貨商 資料庫,共3個表.供貨商表 s s sname 貨物表 p p pname ...

SQL中 IN 與 EXISTS的使用

大家在談到sql優化時,都會說到用exists 代替 in 查詢。現在就談談這兩個的用法。in查詢相當於多個or條件的疊加,這個比較好理解,比如下面的查詢 select from user where userid in 1 2,3 等效於 select from user where userid...

SQL中exists的使用方法

exists用於檢查子查詢是否至少會返回一行資料,該子查詢實際上並不返回任何資料,而是返回值true或false 有乙個查詢如下 複製 如下 select c.customerid,companyname from customers c where exists select orderid fr...