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)
- 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的例子
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) ) && ((a, b) != (e, f)),將(a, b)與(c, d)比較看成坐標比較,只要有一個坐標對不上這個就是不相等的,因此上面的式子可以擴展成為 (a != c || b != d) && (a != e || b != f)
- 第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. 以上是個人的一些觀點總結,歡迎大家批評指教。
