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

来源:http://www.cnblogs.com/Gin-23333/archive/2016/02/16/5193432.html
-Advertisement-
Play Games

in 和 exists 已經成為我們日常查詢時候的常客了。很多時候他們2個都是可以互通實現的,但是,無論兄弟怎麼親,還是會有那麼一些差別的。 先搞個測試表 CREATE TABLE #Tmp1(ID INT,Col1 NVARCHAR(50)) CREATE TABLE #Tmp2(ID INT,T


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 效果好的地方!!一切要看實際哦~一定要測試~

 

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 嗷嗚嗷嗚嗷嗚 1 // 將視圖作為屬性方便後面執行多個不同動畫 2 _myView = [[UIView alloc] init]; 3 _myView.layer.position = CGPointMake(100, 100); 4 _myView.layer.bounds = CGRectMa
  • 今天用Xcode打包IPA文件給同事,結果提示import時,提示證書missing,找了半天沒發現問題,後來打開鑰匙串,發現證書全失效了!!!嚇死寶寶了~~~~(>_<)~~~~ 然後,處理它。 1.打開鑰匙串 2.進行如下圖操作,打開證書信息雙擊或右鍵均可 3.再次去打包,成功 註意:分享轉載請
  • Moshi 是一個現代化的JSON庫針對Android和Java。它可以很容易地解析JSON成Java對象: String json = ...; Moshi moshi = new Moshi.Builder().build(); JsonAdapter<BlackjackHand> jsonAd
  • 自定義視圖,視圖控制器,視圖控制器指定視圖,loadView,viewDidLoad,MVC,屏幕旋轉,記憶體警告
  • 迴圈廣告我們在開發中已經是熟得不能再熟了,今天整理這篇scrollview三屏復用廣告 原理使用scrollview里的三個imageview分別去載入不同的圖片,用少量的資源來顯示大量或不確定的廣告數量,不然如果用普通方法實現廣告,難道10個廣告用12個scrollview的contentsize
  • 如下圖是側滑的效果圖 實現的功能主要是用ViewDragHelper,用ViewDragHelper來自定義一個側滑面板來實現側滑 如下是自定義的側滑面板 1 package com.demo.sb.widget; 2 3 import com.nineoldandroids.view.ViewHe
  • 一:藍牙設備之間的通訊首要包含了四個進程 設置藍牙設備 尋覓區域網內也許或許匹配的設備 銜接設備 設備之間的數據傳輸 二:詳細編程完結 1. 發動藍牙功用 首要經過調用靜態辦法getDefaultAdapter()獲取藍牙適配器BluetoothAdapter,假如回來為空,則無法繼續執行了。例如安
  • 前言: QQ表情包就用到瞭解壓縮,從網路下載的那麼多表情文件格式並不是一個一個圖片文件,而是多個圖片壓縮而成的表情壓縮包。下麵介紹的是iOS開發中會用到的壓縮和解壓縮的第三方框架的使用。 註意: 這個第三方框架代碼文件夾是SSZipArchive,使用cocoapods搜索也是搜索SSZipArch
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...