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

1.   先討論 in 與 not in中存在NULL的狀況, sql語句以下: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);

 

      執行結果:oracle

result1 result2 result3 result4
1 沒有任何返回值 1 沒有任何返回值

 

      說明:innot 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)測試

  • result1返回結果1顯而易見,1跟2和3相比都不相等, 相似於(1<>2) && (1<>3) 結果爲true因此返回結果1
  • result2中(1<>2) && (1<>3) && (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的例子spa

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);

 

 


      執行結果:code

result5 result6
1 沒有任何返回值

      

      說明: exists與not exists至關於一種邏輯判斷,exists 的本質就是返回一個布爾值,exists測試關聯子查詢是否有數據返回,若是有至少一行返回的話則exists判斷爲真返回true, not exists判斷關聯子查詢是否沒有數據返回, 若是沒有數據返回則判斷爲真,返回true。blog

 

  • result5查詢中因爲NULL不能與任何值做比較,所以天然是不存在t.dummy=null了,關聯查詢返回結果集爲空,not exists邏輯判斷結果爲true, 最終1被查詢出來。
  • result6查詢中存在t.dummy=null, 說不通,關聯查詢返回結果集爲空, 邏輯判斷結果爲false, 最終外層查詢沒有任何結果集返回。

 

3.   最後看一個有挺有意思的查詢,從csdn論壇上看的。table

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)class

  • 第1行的查詢判斷爲true && true 結果爲true、最終字符'true'得以返回。
  • 第3行的查詢判斷爲true && false 結果爲false、最終沒有結果返回。
  • 第5行的查詢判斷爲true && true 結果爲true、 最終字符'true'得以返回。
  • 第7行的查詢判斷爲true && 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.    以上是我的的一些觀點總結,歡迎你們批評指教。select

相關文章
相關標籤/搜索