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

