SQL 特殊狀態(tài)“未知“以及“空值NULL“的判斷
一、新邏輯狀態(tài):未知
- 對(duì)于大多數(shù)其他語(yǔ)言的邏輯判斷,一般只有兩種結(jié)果:
真(TURE)或假(FALSE) - 但在SQL中,還會(huì)有第三種判斷結(jié)果:
未知(UNKNOWN),表示無(wú)法判斷出真或者假。
未知狀態(tài)會(huì)影響傳統(tǒng)邏輯運(yùn)算(與或非等)的結(jié)果,總結(jié)如下:
1. 邏輯與操作
| AND/&& | 真 | 假 | 未知 |
|---|---|---|---|
| 真 | 真 | ||
| 假 | 假 | 假 | |
| 未知 | 未知 | 假 | 未知 |
特別注意:
- 對(duì)于AND運(yùn)算符,只有當(dāng)兩邊的運(yùn)算結(jié)果都為真時(shí),最終結(jié)果才為真
- 真 AND 未知 = 未知, 并不是真
2. 邏輯或操作
| OR | 真 | 假 | 未知 |
|---|---|---|---|
| 真 | 真 | ||
| 假 | 真 | 假 | |
| 未知 | 真 | 未知 | 未知 |
- 對(duì)于OR運(yùn)算符,只要兩邊的運(yùn)算有一個(gè)為真時(shí),最終結(jié)果就為真,否則最終結(jié)果為假或者未知
3. 邏輯非操作
| NOT | 運(yùn)算結(jié)果 |
|---|---|
| 真 | 假 |
| 假 | 真 |
| 未知 | 未知 |
二、SQL中"未知"狀態(tài)的判斷影響
SQL語(yǔ)句中的WHERE、HAVING、CASE表達(dá)式,只返回邏輯運(yùn)算結(jié)果為真的數(shù)據(jù),不返回為假或者未知的數(shù)據(jù)
三、NULL空值
在數(shù)據(jù)庫(kù)中,空值NULL是一個(gè)特殊值,表示缺失或者未知
在SQL語(yǔ)句中,任何數(shù)據(jù)與空值進(jìn)行算術(shù)比較的結(jié)果是未知,而非真或非假.。所以空值NULL無(wú)法通過(guò) “WHERE c1 = NULL” 來(lái)判斷,需要寫成 WHERE c1 IS NULL ,才能作為條件篩選出查詢字段為NULL的數(shù)據(jù)
1. NULL判斷的特殊性
即使兩個(gè)未知數(shù)據(jù)進(jìn)行比較,運(yùn)算結(jié)果也是未知的,比如下面的比較,都得不出TRUE,而是未知。以下例子則判斷為未知
NULL = 0
NULL != 0
NULL = ‘’ (空字符串)
NULL = !‘’
NULL = NULL
NULL = !NULL
因此在WHERE語(yǔ)句中進(jìn)行判斷時(shí),務(wù)必要注意查詢列或者查詢條件(即等號(hào)兩邊的數(shù)據(jù))都有沒有可能為NULL,如果有則要用IS NULL來(lái)判定
替代方案
Mysql提供了<=>運(yùn)算符,即可等值比較,也可空值比較;
-- mysql SELECT 1 <=> 1, NULL <=> NULL;
PostgreSQL提供的是:IS [NOT] DISTINCT FROM
-- postgreSQL SELECT 1 IS DISTINCT FROM 1, NULL IS DISTINCT FROM NULL;
2. NULL對(duì)IN() 運(yùn)算符的影響
IN運(yùn)算符為判斷所給條件是否在某個(gè)集合中。內(nèi)部實(shí)際使用等值運(yùn)算符=來(lái)判斷是否和集合中的每個(gè)元素相等,再用OR串聯(lián)起來(lái)得到最后的邏輯結(jié)果。
SELECT *
FROM student
WHERE name IN("LiLei", "HanMeimei") -- 等同于 WHERE name = "LiLei" OR name = "HanMeimei"
因此如果想通過(guò)IN() 運(yùn)算符中加NULL元素來(lái)將被查字段中的NULL值也篩選出來(lái),實(shí)際是無(wú)法生效的。比如想實(shí)現(xiàn)以下SQL篩選出學(xué)生姓名為NULL的,不會(huì)有效
-- 無(wú)法篩選出name為NULL的記錄
SELECT *
FROM student
WHERE name IN("LiLei", "HanMeimei", NULL)
/* 等同于 WHERE name = "LiLei" OR name = "HanMeimei" or name = NULL
對(duì)于真正name為NULL的數(shù)據(jù),此表達(dá)式最終的結(jié)果為未知,不會(huì)被篩選出來(lái) */
在NOT IN() 中使用NULL,影響會(huì)更大,使得判斷無(wú)法篩選出任何記錄
-- 無(wú)法篩選出任何記錄
SELECT *
FROM student
WHERE name NOT IN("LiLei", "HanMeimei", NULL)
/* 因?yàn)樵涞韧冢?WHERE name != "LiLei" and name != "HanMeimei" and name != NULL.
任何值在最后一句中的判斷結(jié)果都會(huì)為"UNKOWN",使得整個(gè)判斷變?yōu)槲粗?,被過(guò)濾掉 */
3. NULL對(duì)子查詢語(yǔ)句中,ALL()/ANY() 運(yùn)算符的影響
子查詢中,可以通過(guò)比較運(yùn)算符(=、!=、<、<=、>、>=)與ALL、ANY的組合,來(lái)表示等于、不等于、大于…集合中的全部數(shù)據(jù)
SELECT * FROM student WHERE class =ANY ( -- 查找屬于1年級(jí)的學(xué)生 SELECT class FROM teacher WHERE grade = 1 )
ALL運(yùn)算符相當(dāng)于:對(duì)其中每個(gè)選項(xiàng)進(jìn)行比較運(yùn)算符計(jì)算,并用AND運(yùn)算符串聯(lián)IN運(yùn)算符相當(dāng)于:對(duì)其中每個(gè)選項(xiàng)進(jìn)行=運(yùn)算符計(jì)算,并用OR運(yùn)算符串聯(lián)ANY與IN類似,也是由OR運(yùn)算符串聯(lián),比較運(yùn)算符寫于ANY之前;如果是=ANY,則與IN相同
對(duì)于ALL、ANY等運(yùn)算符,后面加上NULL不會(huì)成功篩選出想要的NULL數(shù)據(jù),相反會(huì)導(dǎo)致比較離譜的運(yùn)算結(jié)果
總結(jié)
- 使用IN/NOT IN/ALL/ANY時(shí),切記不要在選項(xiàng)中設(shè)置NULL。對(duì)于子查詢做以上匹配結(jié)果時(shí),也要注意務(wù)必過(guò)濾下NULL數(shù)據(jù)
4. 空值處理
COALESCE函數(shù)
COALESCE(exp1, exp2, exp3, …)接收一個(gè)輸入列表,返回第一個(gè)非NULL的參數(shù);若都為空,則返回NULL
SELECT COALESCE(yuwen_score, shuxue_score, yingyu_score) FROM student
可以用COALESCE將NULL轉(zhuǎn)換為別的默認(rèn)值,類似于CASE WHEN
SELECT COALESCE(yuwen_score, 0) -- 若語(yǔ)文成績(jī)?yōu)镹ULL, 則記為0分 FROM student
NULLIF函數(shù)
NULLIF(exp1, exp2)接收兩個(gè)入?yún)ⅲ喝粝嗟葎t返回NULL;若不等則返回exp1
SELECT NULLIF(yuwen_score, 0) -- 若語(yǔ)文成績(jī)?yōu)?, 則記為NULL;不為0,則取此成績(jī) FROM student
NULLIF函數(shù)最大的目的是被用來(lái)防止除零錯(cuò)誤
SELECT AVG(yuwen_score)/NULLIF(yuwen_score, 0) --若某同學(xué)語(yǔ)文成績(jī)?yōu)?,則分母為NULL(不是0),此時(shí)不會(huì)報(bào)錯(cuò) FROM student
IFNULL函數(shù)
MYSQL與SQLite才有,入?yún)⒅挥袃蓚€(gè),功能是返回兩個(gè)入?yún)⒅械谝粋€(gè)非空的值(可視為入?yún)⒐潭閮蓚€(gè)的COALESCE函數(shù))。注意與NULLIF區(qū)分。
SELECT IFNULL(yuwen_score, 0) -- 若語(yǔ)文成績(jī)?yōu)镹ULL, 則記為0 FROM student
到此這篇關(guān)于SQL 特殊狀態(tài)“未知“以及“空值NULL“的判斷的文章就介紹到這了,更多相關(guān)SQL 未知狀態(tài)及“空值NULL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MS sqlserver 2008數(shù)據(jù)庫(kù)轉(zhuǎn)換成2000版本的方法
這篇文章主要為大家詳細(xì)介紹了MS sqlserver 2008數(shù)據(jù)庫(kù)轉(zhuǎn)換成2000版本的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
必須會(huì)的SQL語(yǔ)句(三) 數(shù)據(jù)插入
這篇文章主要介紹了sqlserver中數(shù)據(jù)插入的sql語(yǔ)句,需要的朋友可以參考下2015-01-01
sql server 2000中禁止創(chuàng)建表(權(quán)限設(shè)置方法)
最近發(fā)現(xiàn)數(shù)據(jù)庫(kù)中發(fā)現(xiàn)了三個(gè)臨時(shí)表,為了安全這里為大家分享下sql server 2000中禁止創(chuàng)建表的方法,網(wǎng)上都么有的,腳本之家小編原創(chuàng)2015-07-07
必須會(huì)的SQL語(yǔ)句(八) 數(shù)據(jù)庫(kù)的完整性約束
這篇文章主要介紹了sqlserver中數(shù)據(jù)庫(kù)的完整性約束使用方法,需要的朋友可以參考下2015-01-01
SqlServer 英文單詞全字匹配詳解及實(shí)現(xiàn)代碼
這篇文章主要介紹了SqlServer 英文單詞全字匹配的相關(guān)資料,并附實(shí)例,有需要的小伙伴可以參考下2016-09-09
sql server 臨時(shí)表 查找并刪除的實(shí)現(xiàn)代碼
考慮使用表變量而不使用臨時(shí)表。當(dāng)需要在臨時(shí)表上顯式地創(chuàng)建索引時(shí),或多個(gè)存儲(chǔ)過(guò)程或函數(shù)需要使用表值時(shí),臨時(shí)表很有用。通常,表變量提供更有效的查詢處理。2008-12-12
必須會(huì)的SQL語(yǔ)句(一) 創(chuàng)建數(shù)據(jù)庫(kù)與刪除數(shù)據(jù)庫(kù)
這篇文章主要介紹了sqlserver創(chuàng)建數(shù)據(jù)庫(kù)與刪除數(shù)據(jù)庫(kù)的語(yǔ)句,需要的朋友可以參考下2015-01-01
SQL Server提示"選定的用戶擁有對(duì)象,所以無(wú)法除去該用戶”
今天在幫朋友弄一臺(tái)服務(wù)器的時(shí)候當(dāng)我需要?jiǎng)h除一個(gè)數(shù)據(jù)庫(kù)里的用戶時(shí),提示如下錯(cuò)誤信息: "選定的用戶擁有對(duì)象,所以無(wú)法除去該用戶" 如何解決呢?2009-04-04

