論關(guān)系型數(shù)據(jù)庫(kù)中 NULL 值對(duì) SQL 查詢語(yǔ)句的影響

假設(shè)有如下一張表,名為 Product(DDL 見本文結(jié)尾):

product_id product_name product_type sale_price purchase_price regist_date
0001 T恤衫 衣服 1000 500 2009-09-20
0002 打孔器 辦公用品 500 320 2009-09-11
0003 運(yùn)動(dòng)T恤 衣服 4000 2800 NULL
0004 菜刀 廚房用具 3000 2800 2009-09-20
0005 高壓鍋 廚房用具 6800 5000 2009-01-15
0006 叉子 廚房用具 500 NULL 2009-09-20
0007 擦菜板 廚房用具 880 790 2008-04-28
0008 圓珠筆 辦公用品 100 NULL 2009-11-11

DISTINCT

在使用 DISTINCT 時(shí)骨宠,NULL 也被視為一類數(shù)據(jù)浮定。NULL 存在于多行中時(shí)相满,也會(huì)被合并為一條 NULL 數(shù)據(jù)。

對(duì)含有 NULL 數(shù)據(jù)的列使用 DISTINCT 關(guān)鍵字:

SELECT DISTINCT purchase_price
  FROM Product;

執(zhí)行結(jié)果為:

purchase_price
500
320
2800
5000
NULL
790

算術(shù)函數(shù)

考慮一下在 SQL 語(yǔ)句中如下運(yùn)算的結(jié)果:

5  + NULL
10 - NULL
1  * NULL
4  / NULL
NULL /  9
NULL /  0

正確答案是全為 NULL桦卒。實(shí)際上所有包含 NULL 的計(jì)算立美,結(jié)果肯定是 NULL

比較謂詞

當(dāng)我們嘗試取出不是進(jìn)貨單價(jià)不是 2800 日元(purchase_price <> 2800)的記錄時(shí):

SELECT product_name, purchase_price
  FROM Product
 WHERE purchase_price <> 2800;

執(zhí)行結(jié)果為:

product_name purchase_price
T恤衫 500
打孔器 320
高壓鍋 5000
擦菜板 790

執(zhí)行結(jié)果中并沒有“叉子”和“圓珠筆”方灾。這兩條記錄由于進(jìn)貨單價(jià)不明(NULL)建蹄,因此無法判定是不是 2800 日元。

當(dāng)你嘗試使用 purchase_price = NULLpurchase_price <> NULL 作為查詢條件時(shí)裕偿,均查詢不到任何記錄洞慎。

實(shí)際上,在 SQL 中嘿棘,比較運(yùn)算符的結(jié)果除了真(TRUE)與假(FALSE)之外劲腿,還有第三種值——不確定(UNKNOWN)
NULL 與所有值比較鸟妙,結(jié)果都為不確定焦人。

替代的,你可以使用 purchase_price IS NULLpurchase_price IS NOT NULL 來查詢你想要的記錄重父。如:

SELECT product_name, purchase_price
  FROM Product
 WHERE purchase_price IS NULL;

執(zhí)行結(jié)果為:

product_name purchase_price
叉子 NULL
圓珠筆 NULL

邏輯謂詞

下列是三值邏輯中 ANDOR 運(yùn)算的真值表:

P Q P AND Q P OR Q
不確定 不確定
不確定 不確定
不確定 不確定 不確定 不確定

使查詢語(yǔ)句 WHERE 子句的值為不確定的記錄花椭,不會(huì)被查詢出來。

聚合

聚合函數(shù)

COUNT(*) 外房午,聚合函數(shù)只對(duì) NULL 以外的對(duì)象進(jìn)行匯總矿辽。

執(zhí)行如下查詢語(yǔ)句,結(jié)果已在注釋中標(biāo)出:

SELECT COUNT(*)
  FROM Product;
-- 結(jié)果為 8

SELECT COUNT(purchase_price)
  FROM Product;
-- 結(jié)果為 6

SELECT SUM(purchase_price)
  FROM Product;
-- 結(jié)果為 12210(500 + 320 + 2800 + 2800 + 5000 + 790)

SELECT AVG(purchase_price)
  FROM Product;
-- 結(jié)果為 2035((500 + 320 + 2800 + 2800 + 5000 + 790) / 6)
-- 注意:分母為 6 而不是 8郭厌,聚合函數(shù)只對(duì) NULL 以外的對(duì)象進(jìn)行匯總

GROUP BY

當(dāng)聚合鍵中包含 NULL 時(shí)嗦锐,也會(huì)將 NULL 作為一組特定的數(shù)據(jù):

SELECT purchase_price, COUNT(*)
  FROM Product
 GROUP BY purchase_price;

執(zhí)行結(jié)果為:

purchase_price COUNT(*)
NULL 2
320 1
500 1
790 1
2800 2
5000 1

排序

使用含有 NULL 的列作為排序鍵時(shí),NULL 會(huì)在結(jié)果的開頭或末尾匯總顯示:

SELECT product_id, product_name, sale_price, purchase_price
  FROM Product
 ORDER BY purchase_price;

執(zhí)行結(jié)果為:

product_id product_name sale_price purchase_price
0006 叉子 500 NULL
0008 圓珠筆 100 NULL
0002 打孔器 500 320
0001 T恤衫 1000 500
0007 擦菜板 880 790
0003 運(yùn)動(dòng)T恤 4000 2800
0004 菜刀 3000 2800
0005 高壓鍋 6800 5000

究竟是在開頭顯示還是在末尾顯示沪曙,并沒有特殊規(guī)定奕污。某些 DBMS 中可以指定 NULL 在開頭或末尾顯示。

附錄

Product 表 DDL

-- MySQL 5.7

CREATE TABLE Product
(product_id      CHAR(4)      NOT NULL,
 product_name    VARCHAR(100) NOT NULL,
 product_type    VARCHAR(32)  NOT NULL,
 sale_price      INTEGER ,
 purchase_price  INTEGER ,
 regist_date     DATE ,
 PRIMARY KEY (product_id));
 
START TRANSACTION;

INSERT INTO Product VALUES ('0001', 'T恤' ,'衣服', 1000, 500, '2009-09-20');
INSERT INTO Product VALUES ('0002', '打孔器', '辦公用品', 500, 320, '2009-09-11');
INSERT INTO Product VALUES ('0003', '運(yùn)動(dòng)T恤', '衣服', 4000, 2800, NULL);
INSERT INTO Product VALUES ('0004', '菜刀', '廚房用具', 3000, 2800, '2009-09-20');
INSERT INTO Product VALUES ('0005', '高壓鍋', '廚房用具', 6800, 5000, '2009-01-15');
INSERT INTO Product VALUES ('0006', '叉子', '廚房用具', 500, NULL, '2009-09-20');
INSERT INTO Product VALUES ('0007', '擦菜板', '廚房用具', 880, 790, '2008-04-28');
INSERT INTO Product VALUES ('0008', '圓珠筆', '辦公用品', 100, NULL, '2009-11-11');

COMMIT;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末液走,一起剝皮案震驚了整個(gè)濱河市碳默,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌缘眶,老刑警劉巖嘱根,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異巷懈,居然都是意外死亡该抒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門顶燕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來凑保,“玉大人冈爹,你說我怎么就攤上這事∨芬” “怎么了频伤?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)芝此。 經(jīng)常有香客問我憋肖,道長(zhǎng),這世上最難降的妖魔是什么婚苹? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任岸更,我火速辦了婚禮,結(jié)果婚禮上膊升,老公的妹妹穿的比我還像新娘坐慰。我一直安慰自己,他們只是感情好用僧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赞咙,像睡著了一般责循。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上攀操,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天院仿,我揣著相機(jī)與錄音,去河邊找鬼速和。 笑死歹垫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的颠放。 我是一名探鬼主播排惨,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼碰凶!你這毒婦竟也來了暮芭?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤欲低,失蹤者是張志新(化名)和其女友劉穎辕宏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體砾莱,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瑞筐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腊瑟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聚假。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡块蚌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出魔策,到底是詐尸還是另有隱情匈子,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布闯袒,位于F島的核電站虎敦,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏政敢。R本人自食惡果不足惜其徙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望喷户。 院中可真熱鬧唾那,春花似錦、人聲如沸褪尝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)河哑。三九已至避诽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間璃谨,已是汗流浹背沙庐。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佳吞,地道東北人拱雏。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像底扳,于是被迫代替她去往敵國(guó)和親铸抑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

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