一、問題背景及介紹
在寫 SQL 條件語句時經常用到 不等於 !=
的篩選條件。此時要注意此條件會將字段為 Null
的數據也當做滿足不等於的條件而將數據篩選掉。(也就是說會忽略過濾掉為 null 的數據,導致數據不准確)。
比如:表A
A1 | B1 |
---|---|
1 | 0 |
2 | 1 |
3 | Null |
執行如下查詢:select * from A where B1 != 1,得到的結果如下:
A1 | B1 |
---|---|
1 | 0 |
第三列 B1為空的也是會篩選掉的。
二、解決方案
要查出第三列只需將 SQL 改為如下語句 即可。
SELECT * FROM A WHERE B1 != 1 OR B1 is Null
上面這種方法最通俗,網上也最多,但是我總是感覺效率太低。目前我使用的方法是:
SELECT * FROM A WHERE IFNULL(B1,'') != 1
開發中遇到的問題,在此做下記錄,謹防下次入坑。
三、原因分析
為什么會這樣呢?這還得從 mysql 的底層開始說起,因為 NULL 不是一個「值」,而是「沒有值」。
「沒有值」不滿足「值不等於1」這個條件,怎么解決可以使用 ifnull() 方法,將 null 轉為空字符串,或者這個字段做出判斷 加上OR a is null。當然使用 ifnull 相率會更好,現在就是先讓大家理解一下。
四、關於 IFNULL 方法 - mysql 中 ifnull() 方法的用法
一般我們在使用 ifnull() 方法的時候,都是類似下面的語句:
IFNULL(expr1,expr2)
如果 expr1 不是 NULL,IFNULL() 返回expr1,否則它返回expr2。IFNULL()返回一個數字或字符串值。
1、將查詢到的結果中的null轉化為指定的字符串
select ifnull(name,'no name') from person; -- name為null時顯示 no name
2、其實在where查詢部分也可以使用 ifnull()
select * from person where ifnull(name,'no name')='no name'; -- name 為 no name 時,及 name 為 null 時的數據均返回
這種使用看起來有點笨,但是在一些應用中可以很好的減少代碼量
3、IFNULL使用的注意事項
數據如下:
現在開始正題:
(1)IFNULL的作用是什么?下面一個簡單的sql和結果說明,如果IFNULL(a,b),a接收的值為null,則返回b,否則返回a;
SELECT IFNULL(NULL,0); -- 0
(2)以下sql語句,大家可以預測下結果,按照IFNULL函數的作用,應該返回0才對,可是結果並不是這樣。
SELECT IFNULL(score,0) FROM student WHERE ID = 4;
返回結果,居然是null,與預期的結果0不一致。
(3)以下語句返回正確結果0;
SELECT IFNULL((SELECT score FROM student WHERE ID = 4),0);
總結:使用 2 方式使用 IFNULL、SUM等函數時,需要確保有查詢記錄,否則也將返回 null 值,當然也可使用 3 方式避免返回 null 值,避免程序中出現NPE異常。