2016年1月31日 星期日

[SQL] 三值邏輯,資料庫 null 在 where 中的運作

解釋下,上上禮拜新人遇到 oracle 裡面 '' 等價於 null,然後上禮拜又遇到下面這個問題

然後激發出我的雞婆個性 XDDD


遇到 null 的時候,我們的是非觀念.... 變得有點奇怪...

為什麼 in (null), not in (null) 都不給我回傳資料,搞毛啊 = =

我們一般的真值表是這樣的:


有一種叫做三值邏輯 Three-Valued Logic (TVL or 3VL),真值表是這樣的:

3VL 引入了"我不知道"的概念,這樣上面的真值表就很合理了!

NOT UNKNOW == UNKNOW
  "非"我不知道 當然還是 我不知道啊 XDD

TRUE AND UNKNOW == UNKNOW
  我吃飽了,但是我不知道你吃飽了沒,所以 "我們兩個都吃飽了"的問題 => 不知道

------

null 在資料庫中就是一個 UNKNOW 值的概念

一個地址欄位被填入了 null 時,正是代表了我不知道地址是哪裡的意思

而 SQL 的 WHERE 部分需要明確的 TRUE/FALSE 結果,來表示這筆資料該不該回傳

當查詢的結果是 UNKNOW 時,這筆資料是不會回傳

直接使用 =, <>, in, not in, exists, not exists 都是在做 TRUE/FALSE 的回答

所以常見的 id = null (UNKNOW)或是 id <> null (NOT UNKNOW)都是不會回傳資料的

我們需要表示不知道的時候,會需要明確地用 is null / is not null 將 3VL 轉回 2VL

------

以下上面第一張圖的解釋:

id in (null)
   id = null 結果是 UNKNOW 不是 TRUE 也不是 FALSE 不回傳

id not in (null)
   not (id = null) 等價於 id <> null ,所以結果是 UNKNOW  不是 TRUE 也不是 FALSE 不回傳

id in ('1', null)
   id = '1' or id = null,當 id 值是 '1' 是 TRUE,當 id 值不是 '1' 是 FALSE
   TRUE OR UNKNOW == TRUEFALSE OR UNKNOW ==  UNKNOW
   所以 id 值是 '1' 結果是 TRUE 會回傳,其他值得情況是 UNKNOW 不回傳

id not in ('1', null)
   not (id = '1' or id = null) 等價於 id <> '1' and id <> null
   參考真值表 TRUE AND UNKNOW == UNKNOWFALSE AND UNKNOW == FALSE
   所以就一筆資料都不會回傳

-----

報告完畢 應該是這樣沒有錯

沒有留言:

張貼留言