1. 先討論 in 與 not in中存在NULL的情況, sql語句如下:
1 select 1 result1 from dual where 1 not in (2, 3); 2 3 4 select 1 result2 from dual where 1 not in (2, 3, null); 5 6 7 select 1 result3 from dual where 1 in (2, 3, null, 1); 8 9 10 select 1 result4 from dual where 1 in (2, 3, null);
執行結果:
result1 result2 result3 result4 1 沒有任何返回值 1 沒有任何返回值
說明:in與not in 會跟括號裡面的值進行比較是否相等從而得出判斷結果,而在oracle中null是無法進行比較的,只能進行判斷IS NULL和IS NOT NULL,這就導致in和not in中與null進行比較時會返回false. a in (b, c, d)相當於(a == b) || (a == c) || (a == d), 而 a not in (b, c, d)則相當於(a != b) && (a != c) && (a != d)
2. 再來看看exists與 not exists的例子
1 select 1 result5 from dual where not exists (select 1 from dual t where t.dummy=null); 2 3 select 1 result6 from dual where exists (select 1 from dual t where t.dummy=null);
執行結果:
說明: exists與not exists相當於一種邏輯判斷,exists 的本質就是返回一個布爾值,exists測試關聯子查詢是否有數據返回,如果有至少一行返回的話則exists判斷為真返回true, not exists判斷關聯子查詢是否沒有數據返回, 如果沒有數據返回則判斷為真,返回true。
3. 最後看一個有挺有意思的查詢,從csdn論壇上看的。
1 select 'true' from dual where (1,2) not in ((2,3),(2,null)); 2 3 select 'true' from dual where (2,1) not in ((2,3),(2,null)); 4 5 select 'true' from dual where (2,1) not in ((2,3),(null,3)); 6 7 select 'true' from dual where (2,1) not in ((2,3),(null,1));
說明:二元值not in判斷,... where (a, b) not in ((c, d), (e, f))類似於((a, b) != (c, d) ) && ((a, b) != (e, f)),將(a, b)與(c, d)比較看成坐標比較,只要有一個坐標對不上這個就是不相等的,因此上面的式子可以擴展成為 (a != c || b != d) && (a != e || b != f)
4. 稍微總結一下:
5. 以上是個人的一些觀點總結,歡迎大家批評指教。
不是絕對的,子查詢記錄少的話not in高,否則用not exists
這個還是要看 在not in 和 not exists 關聯的是不是索引吧。我認為使用not in 之後,索引應該失效,不會使用索引去查詢語句,not exists 會比 not in 快一些吧,效率高點