1. 程式人生 > >oracle 子查詢中null的問題(in 和 not in)

oracle 子查詢中null的問題(in 和 not in)

這裡的in後面的句子可以理解為or拼接,簡單舉例即

in (9566,9839,null)可以等價於mgr=9566 or mgr=9839 or mgr=null,

not in (9566,9839,null)可以等價於not(mgr=9566 or mgr=9839 or mgr=null)或mgr!=9566 and mgr!=9839 and mgr!=null。

為什麼都是or拼接,in可以而not in不可以呢,可以把not in理解為後面的and表示式就知道了,因為mgr=null為null,也就相當於false,導致整個表示式為false,無論傳何值都為false,自然無法返回資料。

當發現not in後的子查詢後面有null值時,可以在子查詢裡用is not null或函式過濾null值。

 

正如所看到的,not in出現了不期望的結果集,存在邏輯錯誤。如果看一下上述兩個select 語句的執行計劃,也會不同,後者使用了hash_aj,所以,請儘量不要使用not in(它會呼叫子查詢),而儘量使用not exists(它會呼叫關聯子查詢)。如果子查詢中返回的任意一條記錄含有空值,則查詢將不返回任何記錄。如果子查詢欄位有非空限制,這時可以使用not in,並且可以通過提示讓它用hasg_aj或merge_aj連線。

如果查詢語句使用了not in,那麼對內外表都進行全表掃描,沒有用到索引;而not exists的子查詢依然能用到表上的索引。所以無論哪個表大,用not exists都比not in 要快。