SQL陷阱 in與not in不是相反的

2021-08-04 05:40:28 字數 2319 閱讀 9647

在sql中,邏輯值與其他程式語言不同,其他程式語言往往只有truefalse,而在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...