exists (sql 返回結果集為真)
not exists (sql 不返回結果集為真)如下: 表A ID NAME 1 A12 A23 A3表B ID AID NAME 1 1 B12 2 B23 2 B3表A和表B是1對多的關系 A.ID => B.AIDSELECT ID,NAMEFROM A WHERE EXIST (SELECT* FROM BWHERE A.ID=B.AID)執行結果為 1 A12 A2
select * from EB where exists (select * from BB where Code=EB.Code) 這句的流程是這樣的 首先 外面的EB表傳進去第一條記錄 進子查詢 。(EB.Code) 接著EB.Code 就和子查詢里的BB表進行對比 如果有那么一條符合EB.CODE=BB.CODE 就返回真 。。。 那么就在外面顯示出來 EB.Code這個值 依次類推
原因可以按照如下分析
SELECT ID,NAME FROM A WHEREEXISTS (SELECT* FROM BWHERE B.AID=1)--->SELECT * FROM B WHERE B.AID=1有值返回真所以有數據SELECT ID,NAMEFROM A WHERE EXISTS (SELECT* FROM BWHERE B.AID=2)--->SELECT * FROM B WHERE B.AID=2有值返回真所以有數據SELECT ID,NAMEFROM A WHERE EXISTS (SELECT* FROM BWHERE B.AID=3)--->SELECT * FROM B WHERE B.AID=3無值返回真所以沒有數據NOT EXISTS 就是反過來 SELECT ID,NAMEFROM A WHERE NOT EXIST (SELECT* FROM BWHERE A.ID=B.AID)執行結果為3 A3
1) select * from T1 where exists(select 1 from T2 whereT1.a=T2.a) ;
2) select * from T1 where T1.a in (select T2.a from T2) ;
exists 用法:
請注意 1)句中的有顏色字體的部分 ,理解其含義;
其中 “select 1 from T2 where T1.a=T2.a” 相當于一個關聯表查詢,相當于
“select 1 fromT1,T2
但是,如果你當當執行 1) 句括號里的語句,是會報語法錯誤的,這也是使用exists需要注意的地方。
“exists(xxx)”就表示括號里的語句能不能查出記錄,它要查的記錄是否存在。
因此“select 1”這里的“1”其實是無關緊要的,換成“*”也沒問題,它只在乎括號里的數據能不能查找出來,是否存在這樣的記錄,如果存在,這 1) 句的where條件成立。
in 的用法:
繼續引用上面的例子
“2) select * from T1 where T1.a in (select T2.a from T2) ”
這里的“in”后面括號里的語句搜索出來的字段的內容一定要相對應,一般來說,T1和T2這兩個表的a字段表達的意義應該是一樣的,否則這樣查沒什么意義。
打個比方:T1,T2表都有一個字段,表示工單號,但是T1表示工單號的字段名叫“ticketid”,T2則為“id”,但是其表達的意義是一樣的,而且數據格式也是一樣的。這時,用2)的寫法就可以這樣:
“select * from T1 where T1.ticketid in (select T2.id from T2)”
Select name from employee where name not in (select name fromstudent);
Select name from employee where not exists (select name fromstudent);
第一句SQL語句的執行效率不如第二句。
通過使用EXISTS,Oracle會首先檢查主查詢,然后運行子查詢直到它找到第一個匹配項,這就節省了時間。Oracle在執行IN子查詢時,首先執行子查詢,并將獲得的結果列表存放在一個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起,待子查詢執行完畢,存放在臨時表中以后再執行主查詢。這也就是使用EXISTS比使用IN通常查詢速度快的原因
select * from Awhere id in(select id from B)
以上查詢使用了in語句,in()只執行一次,它查出B表中的所有id字段并緩存起來.之后,檢查A表的id是否與B表中的id相等,如果相等則將A表的記錄加入結果集中,直到遍歷完A表的所有記錄.可以看出,當B表數據較大時不適合使用in(),因為它會B表數據全部遍歷一次.如:A表有10000條記錄,B表有1000000條記錄,那么最多有可能遍歷10000*1000000次,效率很差.再如:A表有10000條記錄,B表有100條記錄,那么最多有可能遍歷10000*100次,遍歷次數大大減少,效率大大提升.
結論:in()適合B表比A表數據小的情況
select a.* from A awhere exists(select 1 from B b where a.id=b.id)
以上查詢使用了exists語句,exists()會執行A.length次,它并不緩存exists()結果集,因為exists()結果集的內容并不重要,重要的是結果集中是否有記錄,如果有則返回true,沒有則返回false.當B表比A表數據大時適合使用exists(),因為它沒有那么遍歷操作,只需要再執行一次查詢就行.如:A表有10000條記錄,B表有1000000條記錄,那么exists()會執行10000次去判斷A表中的id是否與B表中的id相等.如:A表有10000條記錄,B表有100000000條記錄,那么exists()還是執行10000次,因為它只執行A.length次,可見B表數據越多,越適合exists()發揮效果.再如:A表有10000條記錄,B表有100條記錄,那么exists()還是執行10000次,還不如使用in()遍歷10000*100次,因為in()是在內存里遍歷比較,而exists()需要查詢數據庫,我們都知道查詢數據庫所消耗的性能更高,而內存比較很快.
結論:exists()適合B表比A表數據大的情況
當A表數據與B表數據一樣大時,in與exists效率差不多,可任選一個使用.
新聞熱點
疑難解答