MySQL NULL值處理詳細(xì)說明

在講null之前一铅,我們先看一個(gè)例子
表數(shù)據(jù)如下:

3306>select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | chen  |
|    2 | zhang |
|    3 | NULL  |
+------+-------+
3 rows in set (0.00 sec)

然后我們想查出所有名字不為'chen'的其它行記錄庄敛,我們有可能這樣寫:

3306>select * from t1 where name!='chen';
+------+-------+
| id   | name  |
+------+-------+
|    2 | zhang |
+------+-------+
1 row in set (0.00 sec)

但是結(jié)果好像不太如我們所愿,id為1的那條記錄沒有被查出來黔宛,null肯定和'chen'不相等呀鱼填,為什么會(huì)查不出呢?

NUll值對(duì)于新手來說非常容易混淆联逻,經(jīng)常會(huì)被認(rèn)為null與空字符串''是一樣的搓扯,但事實(shí)上,這兩者是非常不一樣遣妥,NULL表示的是“a missing unknown value”擅编,而字符串''是一個(gè)確定的值,這本質(zhì)上就已經(jīng)不一樣了箫踩。

舉個(gè)例子:

mysql> INSERT INTO t_user (phone) VALUES (NULL);
mysql> INSERT INTO t_user (phone) VALUES ('');

第一條insert語句認(rèn)為這個(gè)手機(jī)號(hào)還不確定是多少爱态,是a missing unknown phone number
第二條代表這個(gè)手機(jī)號(hào)碼是確定的,它的手機(jī)號(hào)碼為空字符串

為了處理和null相關(guān)的比較境钟,在mysql中可以用is null锦担、is not null、<=>慨削、isnull()來測(cè)試比較洞渔,不能用如=、<缚态、<>來和null值比較測(cè)試磁椒,任何值(包括和null本身)與null對(duì)比和函數(shù)運(yùn)算操作結(jié)果都為null

如下三個(gè)例子可以說明問題:

任何與null的相關(guān)操作都為null
3306>SELECT NULL, 1+NULL, CONCAT('Invisible',NULL);
+------+--------+--------------------------+
| NULL | 1+NULL | CONCAT('Invisible',NULL) |
+------+--------+--------------------------+
| NULL |   NULL | NULL                     |
+------+--------+--------------------------+
1 row in set (0.00 sec)

3306>SELECT 1>NULL, 1=NULL, 1!=NULL;
+--------+--------+---------+
| 1>NULL | 1=NULL | 1!=NULL |
+--------+--------+---------+
|   NULL |   NULL |    NULL |
+--------+--------+---------+
1 row in set (0.00 sec)

用指定的函數(shù)操作才能返回0或1
3306 > SELECT 1 IS NULL, 1 IS NOT NULL, 1<=>NULL,NULL<=>NULL;
+-----------+---------------+----------+-------------+
| 1 IS NULL | 1 IS NOT NULL | 1<=>NULL | NULL<=>NULL |
+-----------+---------------+----------+-------------+
|         0 |             1 |        0 |           1 |
+-----------+---------------+----------+-------------+
1 row in set (0.00 sec)

但是呢,凡事都有個(gè)例外:
當(dāng)用distinct玫芦、group by浆熔、order by時(shí),此時(shí)不同的null值被視為相等計(jì)算桥帆。

最重要的是医增,在mysql中慎皱,0和null代表假,其它的任何值都代表真

所以回頭看最開始的例子叶骨,當(dāng)我們的where條件為name!='chen'時(shí)茫多,它與id=1的行進(jìn)行比較,即測(cè)試:
'chen'!='chen'
這個(gè)測(cè)試結(jié)果為0忽刽,為假天揖,所以id=1這一行就不會(huì)被查出來。接下來再測(cè)試:
'zhang'!='chen'
這個(gè)測(cè)試結(jié)果為1跪帝,為真宝剖,所以id=2這一行就可以被查出來。接下來再測(cè)試:
NULL!='chen'
這個(gè)測(cè)試結(jié)果為NULL歉甚,為假,所以id=3這一行就不會(huì)被查出來扑眉。
所以最終的結(jié)果就只有id=2這一行的數(shù)據(jù)被查出來了纸泄。
那如果要達(dá)到我們的目地怎么辦?

3306>select * from t1 where name!='chen' or name is null;
+------+-------+
| id   | name  |
+------+-------+
|    2 | zhang |
|    3 | NULL  |
+------+-------+
2 rows in set (0.01 sec)

或

3306>select * from t1 where ifnull(name,0)!='chen' ;
+------+-------+
| id   | name  |
+------+-------+
|    2 | zhang |
|    3 | NULL  |
+------+-------+
2 rows in set (0.00 sec)

推薦用第一種方法腰素。
因?yàn)閙ysql對(duì)了null列的查找是有查詢優(yōu)化的:

3306>explain select * from test a where a.code='AAAAAA' or a.code is null\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: a
         type: ref_or_null
possible_keys: code
          key: code
      key_len: 21
          ref: const
         rows: 73603
        Extra: Using index condition
1 row in set (0.01 sec)

而第二種在列上加上函數(shù)的查詢時(shí)索引是不起作用的聘裁。

其它注意事項(xiàng)

  1. 用order by ... asc時(shí),null值會(huì)被放在最前面弓千,而用order by ... desc時(shí)衡便,null時(shí)會(huì)被放在最后面,相當(dāng)于null是一個(gè)無窮小的值洋访。

  2. 聚合函數(shù)如count(),min(),sum()是忽略null值的镣陕。唯一的例外是用count(),如
    SELECT COUNT(
    ), COUNT(age) FROM person;
    如上語句是第一個(gè)count(*)是計(jì)算person表總行數(shù)姻政,而第二個(gè)是計(jì)算person表age列非null的行數(shù)

  3. 在MyISAM呆抑、InnoDB和MEMORY引擎中,是可以在包含null值的列添加索引的,而在其它引擎中則必須聲明為not null才可以添加索引

  4. 當(dāng)用load data infile時(shí),空的或者沒有的列將用空字符''代替汁展,如果要導(dǎo)入null值鹊碍,需要在數(shù)據(jù)文件里用\N來表示。

  5. 如果你往timestamp插入null值食绿,則當(dāng)前時(shí)間會(huì)被插入侈咕,如果一個(gè)自增列插入null值,下一個(gè)自增值將會(huì)被插入器紧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耀销,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子品洛,更是在濱河造成了極大的恐慌树姨,老刑警劉巖摩桶,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異帽揪,居然都是意外死亡硝清,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門转晰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芦拿,“玉大人,你說我怎么就攤上這事查邢≌崞椋” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵扰藕,是天一觀的道長缓苛。 經(jīng)常有香客問我,道長邓深,這世上最難降的妖魔是什么未桥? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮芥备,結(jié)果婚禮上冬耿,老公的妹妹穿的比我還像新娘。我一直安慰自己萌壳,他們只是感情好亦镶,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著袱瓮,像睡著了一般缤骨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上尺借,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天荷憋,我揣著相機(jī)與錄音,去河邊找鬼褐望。 笑死勒庄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的瘫里。 我是一名探鬼主播实蔽,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼谨读!你這毒婦竟也來了局装?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铐尚,沒想到半個(gè)月后拨脉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡宣增,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年玫膀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片爹脾。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帖旨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出灵妨,到底是詐尸還是另有隱情解阅,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布泌霍,位于F島的核電站货抄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏朱转。R本人自食惡果不足惜碉熄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肋拔。 院中可真熱鬧,春花似錦呀酸、人聲如沸凉蜂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽窿吩。三九已至,卻和暖如春错览,著一層夾襖步出監(jiān)牢的瞬間纫雁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工倾哺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留轧邪,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓羞海,卻偏偏與公主長得像忌愚,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子却邓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理硕糊,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 134,659評(píng)論 18 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法简十,類相關(guān)的語法檬某,內(nèi)部類的語法,繼承相關(guān)的語法螟蝙,異常的語法恢恼,線程的語...
    子非魚_t_閱讀 31,639評(píng)論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 3,811評(píng)論 0 11
  • 什么是數(shù)據(jù)庫? 數(shù)據(jù)庫是存儲(chǔ)數(shù)據(jù)的集合的單獨(dú)的應(yīng)用程序胶逢。每個(gè)數(shù)據(jù)庫具有一個(gè)或多個(gè)不同的API厅瞎,用于創(chuàng)建,訪問初坠,管理...
    chen_000閱讀 4,035評(píng)論 0 19