NULL是SQL常見(jiàn)的關(guān)鍵字之一,表示“空,無(wú)”的意思。它在SQL中是一種獨(dú)特的存在,今天來(lái)匯總一下與它相關(guān)的知識(shí)點(diǎn),看看這些你都知道嗎?
先貼一下我們的原始數(shù)據(jù),是一個(gè)只有1列的表,表名為example,很簡(jiǎn)單:
1.NULL是一種特殊的值,對(duì)某字段使用distinct 關(guān)鍵字時(shí),NULL和一般值一樣,都會(huì)排重,只保留一個(gè)值。
2.不能對(duì)NULL值使用比較運(yùn)算符
直白地講,不能對(duì)null值使用等號(hào)(=)或者不等號(hào)(!=)進(jìn)行比較,要使用is null 和 is not null。
有一種情況需要注意,假設(shè)我們需要取col不為2的所有col值,包括null。不能只寫(xiě)where col <> '2',因?yàn)檫@樣的寫(xiě)法不會(huì)包括NULL值。我們需要寫(xiě)成where col <> '2' or col is null。
3.count(*)會(huì)統(tǒng)計(jì)null值,count(列名)不包括null值。
4.含NULL值的運(yùn)算結(jié)果都為NULL,如下面圖所示(點(diǎn)擊查看大圖)
5.使用sum函數(shù)和avg函數(shù)時(shí),相應(yīng)列中包含NULL的,會(huì)發(fā)生什么?
sum和avg函數(shù)作用于含有NULL的列,NULL值不參與計(jì)算。上面圖中,sum(col) 是1+2+2+3=8。avg(col) 是(1+2+2+3)/4=2,注意分母是4而不是6。如果需要將NULL值當(dāng)作0值參與到運(yùn)算中,可以用case when的方式進(jìn)行判斷賦值。
select sum(case when col is null then 0 else col end) from example;#結(jié)果是8
select avg(case when col is null then 0 else col end) from example;#分母是6,結(jié)果是1.33
除此外,在使用max,min時(shí),也會(huì)忽略NULL值。事實(shí)上,聚合函數(shù)如果以列名為參數(shù),那么在計(jì)算之前就會(huì)把NULL 排除在外。
6.如果某列含有null,使用group by 進(jìn)行聚合時(shí),null值會(huì)單獨(dú)保留一行。
這一點(diǎn)和第一點(diǎn)有點(diǎn)類(lèi)似,見(jiàn)下面代碼。
7.null占用的空間是多少?
我們?cè)谠瓟?shù)據(jù)的基礎(chǔ)上插入了一行空字符串的數(shù)據(jù)。然后來(lái)看每一個(gè)值所占用的空間。可以看到,NULL所占的空間是NULL,是占用空間的,而空字符串長(zhǎng)度是0,是不占用空間的。
NULL columns require additional space in the row to record whether their values are NULL.
NULL列需要行中的額外空間來(lái)記錄它們的值是否為NULL。
有一個(gè)比喻很恰當(dāng):空值就像是一個(gè)真空狀態(tài)杯子,什么都沒(méi)有,而NULL值就是一個(gè)裝滿(mǎn)空氣的杯子,雖然看起來(lái)都是一樣的,但是有著本質(zhì)的區(qū)別。
補(bǔ)充說(shuō)明:對(duì)于空值的判斷需要用=,!= 等算數(shù)運(yùn)算符,而NULL值不行。count等聚合函數(shù)會(huì)忽略NULL值,但不會(huì)忽略空值。
8.對(duì)NULL進(jìn)行排序,結(jié)果如何?
上面的結(jié)果,升序排序,NULL在最開(kāi)頭,但這并不能說(shuō)明NULL比1小,因?yàn)槲覀兦懊嫣岬绞遣荒軐?duì)NULL使用比較運(yùn)算符的。這里的結(jié)果只是把NULL放在了開(kāi)頭顯示,可能在另外的數(shù)據(jù)庫(kù)中,會(huì)統(tǒng)一放到結(jié)尾顯示。
9.大多數(shù)函數(shù)作用于NULL,結(jié)果都是NULL,如concat函數(shù),abs函數(shù)等。但COALESCE函數(shù)除外,它返回第一個(gè)不為NULL的值。我們常會(huì)看到的NVL函數(shù)是該函數(shù)的簡(jiǎn)化版本,類(lèi)似的函數(shù)還有IFNULL。
SELECT COALESCE(NULL, 1) AS col_1,
COALESCE(NULL, 'test', NULL) AS col_2,
COALESCE(NULL, NULL, '2009-11-01') AS col_3;
--結(jié)果:1 test 2009-11-01
10.NULL的其他作用
NULL多用在字段約束中,如非空約束可以用NOT NULL表示。NULL經(jīng)常用在case表達(dá)式中的ELSE子句中:case when <條件> else NULL end,else的部分也可以不寫(xiě),但為了易讀性,還是建議寫(xiě)。
小結(jié)
對(duì)NULL常用的知識(shí)點(diǎn)總結(jié)如下面的思維導(dǎo)圖,歡迎大家補(bǔ)充。(在有些地方看到了在插入和更新數(shù)據(jù)時(shí)NULL的注意事項(xiàng)和索引相關(guān)的知識(shí),由于用的比較少,就不放在這里了,可以參考文末鏈接自行學(xué)習(xí))