SQL中三值邏輯和NULL的具體使用
在SQL中,三值邏輯是一個(gè)重要概念,它的存在主要是由于 NULL 值的引入。NULL 代表未知值,它既不是空字符串,也不是數(shù)字 0,而是一個(gè)特殊的標(biāo)記,表示數(shù)據(jù)缺失或不可用。
在SQL中,由于NULL值的存在,導(dǎo)致它使用了一種特殊的邏輯作用法:三值邏輯 (Three-Valued Logic, 3VL)
其包括三個(gè)任何邏輯計(jì)算的可能結(jié)果:
TRUE (真)
FALSE (假)
UNKNOWN (未知)
NULL在SQL中表示“未知”或“缺失的值”,它與普通的值有很大區(qū)別。由于NULL表示未知值,所以任何與NULL進(jìn)行運(yùn)算的結(jié)果都應(yīng)該是UNKNOWN,而不是TRUE或FALSE。
NULL的特性
NULL并不是一個(gè)具體值,而是一個(gè)特殊狀態(tài),其具有如下特性:
NULL不能相互比較:NULL = NULL結(jié)果不是TRUE,而是UNKNOWN。NULL參與數(shù)值運(yùn)算,結(jié)果為NULL:NULL + 10的結(jié)果仍然是NULL。NULL參與邏輯運(yùn)算,會(huì)影響邏輯結(jié)果:TRUE AND NULL,結(jié)果是UNKNOWNFALSE OR NULL,結(jié)果是UNKNOWN
如果WHERE條件結(jié)果為UNKNOWN,那么該記錄將不會(huì)被查詢結(jié)果包含。
NULL在SQL邏輯運(yùn)算中的影響
1. 邏輯運(yùn)算 (AND, OR, NOT)
AND運(yùn)算
| 表達(dá)式 | 結(jié)果 |
|---|---|
| TRUE AND TRUE | TRUE |
| TRUE AND FALSE | FALSE |
| TRUE AND UNKNOWN | UNKNOWN |
| FALSE AND UNKNOWN | FALSE |
| UNKNOWN AND UNKNOWN | UNKNOWN |
OR運(yùn)算
| 表達(dá)式 | 結(jié)果 |
|---|---|
| TRUE OR UNKNOWN | TRUE |
| FALSE OR UNKNOWN | UNKNOWN |
| UNKNOWN OR UNKNOWN | UNKNOWN |
NOT運(yùn)算
| 表達(dá)式 | 結(jié)果 |
|---|---|
| NOT TRUE | FALSE |
| NOT FALSE | TRUE |
| NOT UNKNOWN | UNKNOWN |
2. NULL參與比較 (=, !=, >, <, etc.)
| 表達(dá)式 | 結(jié)果 |
|---|---|
| NULL = NULL | UNKNOWN |
| NULL != NULL | UNKNOWN |
| NULL > 10 | UNKNOWN |
| NULL < 10 | UNKNOWN |
| NULL IS NULL | TRUE |
| NULL IS NOT NULL | FALSE |
3. NULL在IN 和 NOT IN中的影響
如果 NULL 出現(xiàn)在 IN 或 NOT IN 語(yǔ)句中,會(huì)導(dǎo)致不可預(yù)期的結(jié)果:
SELECT * FROM users WHERE age IN (20, 30, NULL);
由于 NULL 是未知值,SQL 不知道 NULL 是否屬于 age,導(dǎo)致 UNKNOWN,最終查詢只會(huì)匹配 age=20 和 age=30,但不會(huì)匹配 NULL。
更嚴(yán)重的問(wèn)題出現(xiàn)在 NOT IN 中:
SELECT * FROM users WHERE age NOT IN (20, 30, NULL);
由于 NULL 在 IN 語(yǔ)句中會(huì)返回 UNKNOWN,整個(gè) NOT IN 變成 UNKNOWN,最終不會(huì)返回任何數(shù)據(jù)。
解決方法:
SELECT * FROM users WHERE age NOT IN (20, 30) OR age IS NULL;
4. NULL在DISTINCT、GROUP BY 和 ORDER BY 中
DISTINCT 視
NULL為相同值:SELECT DISTINCT category FROM products;
如果
category列中有多個(gè)NULL,DISTINCT只會(huì)保留一個(gè)NULL。GROUP BY 視
NULL為一個(gè)分組:SELECT category, COUNT(*) FROM products GROUP BY category;
所有
NULL值會(huì)被歸為同一組。ORDER BY 處理
NULL:SELECT * FROM employees ORDER BY salary ASC;
NULL默認(rèn)排在最前或最后,具體行為取決于數(shù)據(jù)庫(kù):PostgreSQL:
NULLS FIRST或NULLS LASTMySQL:
NULL默認(rèn)排在最前SQL Server:
NULL默認(rèn)排在最前
5. NULL在 COALESCE 和 IFNULL 處理
要避免 NULL 影響查詢,可以使用 COALESCE 或 IFNULL 進(jìn)行處理:
COALESCE(expr1, expr2, ..., exprN):返回第一個(gè)非NULL值SELECT name, COALESCE(email, '未知') AS email FROM users;
IFNULL(expr, default_value)(MySQL 專用)SELECT name, IFNULL(email, '未知') AS email FROM users;
NULL 在 JOIN 中的影響
如果 NULL 存在于 JOIN 的關(guān)聯(lián)列中,則該行不會(huì)被匹配:
SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.id;
如果 orders.customer_id 是 NULL,= NULL 結(jié)果是 UNKNOWN,導(dǎo)致 INNER JOIN 失敗。
LEFT JOIN 可以保留 orders 但 customers 數(shù)據(jù)為 NULL。
如何正確處理 NULL
查詢時(shí)使用 IS NULL 和 IS NOT NULL
SELECT * FROM users WHERE email IS NULL;
避免 NULL 影響邏輯運(yùn)算
SELECT * FROM orders WHERE discount IS NULL OR discount > 10;
在 JOIN 中考慮 NULL 可能帶來(lái)的問(wèn)題
SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.id WHERE customers.id IS NOT NULL;
使用 COALESCE() 處理 NULL
SELECT name, COALESCE(email, '未知') AS email FROM users;
正確使用 NOT IN
SELECT * FROM users WHERE age NOT IN (20, 30) OR age IS NULL;
總結(jié)(重點(diǎn))
- NULL 代表未知,不是空字符串或 0。
- SQL 采用三值邏輯(TRUE, FALSE, UNKNOWN),導(dǎo)致 NULL 參與運(yùn)算時(shí)可能返回 UNKNOWN。
- NULL 不能用 = 直接比較,而要使用 IS NULL 和 IS NOT NULL。
- NULL 可能影響 JOIN、GROUP BY、ORDER BY、IN/NOT IN 等查詢,必須小心處理。
- 使用 COALESCE()、IFNULL() 等函數(shù)可以避免 NULL 帶來(lái)的問(wèn)題。
到此這篇關(guān)于SQL中三值邏輯和NULL的具體喲使用的文章就介紹到這了,更多相關(guān)SQL 三值邏輯和NULL內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQLServer中Partition By及row_number 函數(shù)使用詳解
partition by關(guān)鍵字是分析性函數(shù)的一部分,partition by用于給結(jié)果集分組,如果沒(méi)有指定那么它把整個(gè)結(jié)果集作為一個(gè)分組,本文給大家介紹SQLServer中Partition By及row_number 函數(shù)使用詳解,需要的朋友參考下2015-11-11
SQL Server的Windows身份驗(yàn)證和sa登錄都被禁用的完美解決方法
當(dāng)SQL Server的Windows賬戶被誤刪且sa禁用時(shí),會(huì)導(dǎo)致登錄失敗,解決方法是通過(guò)單用戶模式啟動(dòng)服務(wù),賦予管理員權(quán)限,使用SQLCMD重置sa密碼,最后重啟服務(wù)恢復(fù)訪問(wèn),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2025-09-09
SQLServer實(shí)現(xiàn)Ungroup操作的示例代碼
本文主要介紹了SQLServer實(shí)現(xiàn)Ungroup操作的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
SqlServer?多種分頁(yè)方式?詳解(含簡(jiǎn)單速度測(cè)試)
這篇文章主要介紹了SqlServer?多種分頁(yè)方式?(含簡(jiǎn)單速度測(cè)試),附帶50萬(wàn)數(shù)據(jù)分頁(yè)時(shí)間[本機(jī)訪問(wèn)|已重啟SQL服務(wù)|無(wú)其他程序干擾][非索引排序],需要的朋友可以參考下2022-12-12
命令行啟動(dòng)mssqlserver服務(wù)的方法示例
這篇文章主要介紹了命令行啟動(dòng)mssqlserver服務(wù)的方法,大家參考使用2013-11-11
SQL Server 批量插入數(shù)據(jù)的完美解決方案
這篇文章主要介紹了SQL Server 批量插入數(shù)據(jù)的完美解決方案,需要的朋友可以參考下2020-12-12
在SQL觸發(fā)器或存儲(chǔ)過(guò)程中獲取在程序登錄的用戶
每個(gè)用戶可以登錄系統(tǒng),在程序中操作數(shù)據(jù)(添加,更新和刪除)需要實(shí)現(xiàn)記錄操作跟蹤。是誰(shuí)添加,更新和刪除的,這些信息將會(huì)插入至AuditLog表中2012-01-01

