今天說一下where 中 exists 和 in 里面的一些區別


in 和 exists 已經成為我們日常查詢時候的常客了。很多時候他們2個都是可以互通實現的,但是,無論兄弟怎么親,還是會有那么一些差別的。

先搞個測試表

CREATE TABLE #Tmp1(ID INT,Col1 NVARCHAR(50))

CREATE TABLE #Tmp2(ID INT,T1ID INT,Col1 NVARCHAR(50),Col2 NVARCHAR(50))

INSERT INTO #Tmp1
        ( ID, Col1 )
VALUES  ( 1,  N'AAA'),( 2,  N'BBB'),( 3,  N'CCC'),( 4,  N'DDD')

INSERT INTO #Tmp2
        ( ID, T1ID, Col1, Col2 )
VALUES  ( 1, 1, N'aa1',N'aa!!'),( 5, 1, N'aa2',N'vv!!'),( 6, 3, N'cc3',N'VV!!')

然后一般來說,查#Tmp1 的ID存在於#Tmp2里面的數據,以下2個語句都是等價的~

SELECT * FROM #Tmp1 a
    WHERE EXISTS(SELECT * FROM #Tmp2 WHERE a.ID = T1ID)

SELECT * FROM #Tmp1
    WHERE ID IN (SELECT T1ID FROM #Tmp2)

ID          Col1
----------- --------------------------------------------------
1           AAA
3           CCC

ID          Col1
----------- --------------------------------------------------
1           AAA
3           CCC

看~查到的是一樣的。然后現在要給點注意一點的地方了~

1、 使用exists 的時候因為exists后面跟的只是一個bool ,所以在exists() 括號里面跟在 select 和from之間,其實寫什么都不重要,只要條件有結果返回,就OK。比方說

SELECT * FROM #Tmp1 a
    WHERE EXISTS(SELECT NULL FROM #Tmp2 WHERE a.ID = T1ID)

SELECT * FROM #Tmp1 a
    WHERE EXISTS(SELECT * FROM #Tmp2 WHERE 1=0)

ID          Col1
----------- --------------------------------------------------
1           AAA
3           CCC

ID          Col1
----------- --------------------------------------------------

先看第二句,因為子查詢里面是一個恆假的表達式,並不返回任何行數,所以,外部的查詢結果一行都不會出來。這個好理解。

第一句即使你填的是select null 也沒所謂,因為只要有結果集返回,就OK了,甚至改成

SELECT * FROM #Tmp1 a
    WHERE EXISTS(SELECT null) 

ID          Col1
----------- --------------------------------------------------
1           AAA
2           BBB
3           CCC
4           DDD
也全部返回了。為什么,因為子查詢里面每一個都有一行 null 返回出來,那 exists()的判定就是真。所以每一行都會被返回。這個是要注意的。

2 使用 in 的注意事項。
使用 in 的注意事項最主要是在相關子查詢上面,非相關子查詢倒是沒有什么要特別注意的。但是有一個原則

  比方說將上面一個語句改成一個相關子查詢,在子查詢里面引用了#Tmp1 的ID,然后就變成以下的結果

SELECT * FROM #Tmp1 a
    WHERE ID IN (SELECT T1ID FROM #Tmp2 WHERE a.ID = T1ID)

ID          Col1
----------- --------------------------------------------------
1           AAA
3           CCC

感知不明顯是吧,再改動一下,以下這句在實際中並大部分情況並沒有任何的意義,只是用於示例。

SELECT * FROM #Tmp1 a
    WHERE ID IN (SELECT ID FROM #Tmp2 )

ID          Col1
----------- --------------------------------------------------
1           AAA

看看這個語句,從執行結果來看,你可以知道是#Tmp2里面的ID,但有沒有懷疑過是#Tmp1 自身的ID呢?能夠引用嗎?可以!!所以如以下栗子,有時候真會出現這種情況的喲~小心小心再小心哦~

SELECT * FROM #Tmp1 a
    WHERE ID IN (SELECT a.ID FROM #Tmp2 )

ID          Col1
----------- --------------------------------------------------
1           AAA
2           BBB
3           CCC
4           DDD

 

3、 使用 in  的時候,尤其注意一個值 Null  ! 可能在 in (select ID from XXX) 的時候感知不明顯,然而在 not in (select ID from XXX) 的時候!假如 ID 有一個是 Null ~恭喜你~整個結果集都不會返回值啦~~這就是任何值和Null比對都會是unknow 的結果擼~~╮(╯_╰)╭ ~知道會出問題才要小心哦~

 

4、 效率與性能 ——很多文章都有說這個,在XXX地方用exists 比較好,在ZZZ地方用 in 比較好~我的觀點是。即使是 XXX 的場景,也有 in 比 exists 效果好的地方!!一切要看實際哦~一定要測試~

 

額~大家應該都上班了~大家洗樓愉快~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM