1. 程式人生 > >oralce中exists not exists in not in對於NULL的處理

oralce中exists not exists in not in對於NULL的處理

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) %26%26 (a != c) %26%26 (a != d) result1返回結果1顯而易見,1跟2和3相比都不相等, 類似於(1<>2) %26%26 (1<>3) 結果為true所以返回結果1 result2中(1<>2) %26%26 (1<>3) %26%26 (1<>NULL)前面兩個都是true可最後1跟NULL進行比較為false,一招走錯滿盤皆輸就是這個道理,最終結果為false,因此沒有返回結果 result3中(1 == 2) || (1 == 3) || (1 == NULL) || (1 == 1)前面三個表示式都是false,但最後一個表示式為true最終結果也就為真了,因此返回1。 result4中(1 == 2) || (1 == 3) || (1 == NULL)三個表示式都為false, 最終結果也就為false了, 無任何結果集返回。 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); 執行結果: result5 result6 1 沒有任何返回值 說明: exists與not exists相當於一種邏輯判斷,exists 的本質就是返回一個布林值,exists測試關聯子查詢是否有資料返回,如果有至少一行返回的話則exists判斷為真返回true, not exists判斷關聯子查詢是否沒有資料返回, 如果沒有資料返回則判斷為真,返回true。 result5查詢中由於NULL不能與任何值作比較,因此自然是不存在t.dummy=null了,關聯查詢返回結果集為空,not exists邏輯判斷結果為true, 最終1被查詢出來。 result6查詢中存在t.dummy=null, 說不通,關聯查詢返回結果集為空, 邏輯判斷結果為false, 最終外層查詢沒有任何結果集返回。 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) ) %26%26 ((a, b) != (e, f)),將(a, b)與(c, d)比較看成座標比較,只要有一個座標對不上這個就是不相等的,因此上面的式子可以擴充套件成為 (a != c || b != d) %26%26 (a != e || b != f) 第1行的查詢判斷為true %26%26 true 結果為true、最終字元'true'得以返回。第3行的查詢判斷為true %26%26 false 結果為false、最終沒有結果返回。第5行的查詢判斷為true %26%26 true 結果為true、 最終字元'true'得以返回。第7行的查詢判斷為true %26%26 false 結果為false、 最終沒有結果返回。 4. 稍微總結一下: in 在a in (b, c, d, ... , null)中, 括號裡面的比較值裡面存在NULL的話, 看其它比較值裡面是否有跟a相等的值存在, 如果有則返回true, 否則返回false. not in 在 a not in (b, c, d,..., null)中,如果括號裡面存在NULL的話, 則一律返回false. exists 在 exists的關聯查詢條件裡面如果存在NULL的話,則內部查詢是查詢不出結果的,不符合exists至少有一行結果集返回的判斷, 因此返回false. not exists 在not exists的關聯查詢條件裡面如果存在NULL的話,則內部查詢也是查詢不出結果的,符合not exists對於沒有結果集返回的預期判斷, 因此返回true. 5. 以上是個人的一些觀點總結,歡迎大家批評指教。