在sql中,邏輯值與其他程式語言不同,其他程式語言往往只有true
和false
,而在sql中,還多了乙個值unknown
,當與null進行比較時會出現這種值,如(1==null)結果為unknown
。下面看看維基百科的詳細說明。
資料庫查詢語言sql實現三值邏輯作為處理null欄位內容的一種方式。sql使用null來表示在資料庫中缺失資料。如果乙個欄位不包含定義的值,對於sql這意味著實際的值存在,但是這個值當前沒有記錄在資料庫中。注意缺失的值不同於數值零或零長度字串值;這兩者都表示已知的值。比較任何東西於null—即使是另乙個null—結果是unknown真值狀態。例如,考慮下列sql表示式:
city = 'paris'
在sql中,在city欄位中的null值表示在理論中導致這個表示式被確認為要麼true(比如city包含'paris')要麼false(比如city包含'philadelphia')的乙個缺失的值。樣例sql表示式依據如下規則確認:
對於在city欄位中有文字串'paris'的任何記錄結果為true
對於在city欄位中有null的任何記錄結果為unknown
在所有其他情況結果為false
正是因為存在著第三值unknown
,所以容易導致開發者掉入下面的陷阱。
首先假設我們有乙個雇員表,雇員有身份證號,姓名,性別,3個屬性,其中只有性別可以為null,建表語句如下:
create
table
`emp` (
`id`
varchar(18) not
null,
`ename`
varchar(20) not
null,
`e***` tinyint(4) default
null,
primary
key (`id`)
);
這時候,我們往表裡寫入一條資料,(445121199001011111,小明,0)
,(445121199001012222,小紅,1)
,(445121199002021122,小江,null)
。其中0表示性別為男,1表示性別為女。
那麼接下來,我們用in進行查詢,查詢語句如下:
select * from emp where e*** in (0,1);
這條語句的意圖是想查詢性別為男或性別為女的,無性別的將被忽略。很顯然,執行語句的結果集數量為2,即查出了小明和小紅。
我們來看另外一條語句:
select * from emp where e*** not
in (0,1);
這條語句原本的意圖是想查出性別不是男也不是女的,也就是查出小江的資料。但是結果卻是空集。一條資料也沒有!
回顧sql語法,我們知道執行in或not in時,我們是按照返回的布林值的真或假,來決定是否將資料加入結果集。那麼當判斷返回的值為unknown
時,那麼資料必然不會被加入結果集。如果還不明朗,我們可以看看not in的等價關係。
e*** not
in(0,1)等價於:
e*** != any(0,1),也等價於
e*** != 0
and e*** != 1
注意這裡,e*** != 0 and e*** != 1
。當e***為null
時,根據上面的內容,我們知道e***!=0
會返回unknown
,整個表示式的返回值也為unknown
。再看看具體資料,小江的e***為null
,那麼小江的這一條記錄,返回值為unknown
,故不會被加到結果集。
有了上面的鋪墊,我們在使用in或not in時,就應該更加的小心謹慎(其他返回值為布林型別的也同理)。尤其是子查詢,下面是常見的例子
select * from emp where emp.`e***`
notin (select e*** from emp)
上面的返回集為空集。注意這裡子查詢直接使用了emp表,僅僅為了對應上面的結果。在日常開發中,該子查詢的emp表可能為任意的關聯表,只要該關聯表中,存在有e***為null的資料,都會導致最終查詢結果為空集。 not in 和 in的陷阱
1 not in 和in 根據某個字段查詢如 not in 3 查不出這個欄位為空的資料 2 not in 和 in 在 查詢時,條件裡不能存在null,如not in null,3 這樣子是查詢不出結果的 還有個陷阱是 select count 1 from mt bdg three1 where...
sql裡面的in和notin
sql和pyspark是類似的 rdddata sc.parallelize row c class1 s 50 row c class2 s 40 row c class3 s none row c class2 s 49 row c class3 s 29 row c class1 s 78 t...
sql優化 in 和 not in 語句
why?in 和 not in 是比較常用的關鍵字,為什麼要盡量避免呢?1 效率低 可以參看我之前遇到的乙個例子 小問題筆記 九 sql語句not in 效率低,用 not exists試試 2 容易出現問題,或查詢結果有誤 不能更嚴重的缺點 以 in 為例。建兩個表 test1 和 test2 c...