SQL中如何使用EXISTS替代IN


原創作品,可以轉載,但是請標注出處地址http://www.cnblogs.com/V1haoge/p/6385312.html

  我們在程序中一般在做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關聯組合成一張虛表,所有的查詢操作都在這張虛表上完成,操作的是同一張表,當然就不會出現之前的那種情況了!


免責聲明!

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



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