今天說一下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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...