SQL中三值逻辑和NULL的具体使用
作者:昊昊该干饭了
在SQL中,三值逻辑是一个重要概念,它的存在主要是由于 NULL 值的引入。NULL 代表未知值,它既不是空字符串,也不是数字 0,而是一个特殊的标记,表示数据缺失或不可用。
在SQL中,由于NULL值的存在,导致它使用了一种特殊的逻辑作用法:三值逻辑 (Three-Valued Logic, 3VL)
其包括三个任何逻辑计算的可能结果:
TRUE (真)
FALSE (假)
UNKNOWN (未知)
NULL在SQL中表示“未知”或“缺失的值”,它与普通的值有很大区别。由于NULL表示未知值,所以任何与NULL进行运算的结果都应该是UNKNOWN,而不是TRUE或FALSE。
NULL的特性
NULL并不是一个具体值,而是一个特殊状态,其具有如下特性:
NULL不能相互比较:NULL = NULL结果不是TRUE,而是UNKNOWN。NULL参与数值运算,结果为NULL:NULL + 10的结果仍然是NULL。NULL参与逻辑运算,会影响逻辑结果:TRUE AND NULL,结果是UNKNOWNFALSE OR NULL,结果是UNKNOWN
如果WHERE条件结果为UNKNOWN,那么该记录将不会被查询结果包含。
NULL在SQL逻辑运算中的影响
1. 逻辑运算 (AND, OR, NOT)
AND运算
| 表达式 | 结果 |
|---|---|
| TRUE AND TRUE | TRUE |
| TRUE AND FALSE | FALSE |
| TRUE AND UNKNOWN | UNKNOWN |
| FALSE AND UNKNOWN | FALSE |
| UNKNOWN AND UNKNOWN | UNKNOWN |
OR运算
| 表达式 | 结果 |
|---|---|
| TRUE OR UNKNOWN | TRUE |
| FALSE OR UNKNOWN | UNKNOWN |
| UNKNOWN OR UNKNOWN | UNKNOWN |
NOT运算
| 表达式 | 结果 |
|---|---|
| NOT TRUE | FALSE |
| NOT FALSE | TRUE |
| NOT UNKNOWN | UNKNOWN |
2. NULL参与比较 (=, !=, >, <, etc.)
| 表达式 | 结果 |
|---|---|
| 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 出现在 IN 或 NOT IN 语句中,会导致不可预期的结果:
SELECT * FROM users WHERE age IN (20, 30, NULL);
由于 NULL 是未知值,SQL 不知道 NULL 是否属于 age,导致 UNKNOWN,最终查询只会匹配 age=20 和 age=30,但不会匹配 NULL。
更严重的问题出现在 NOT IN 中:
SELECT * FROM users WHERE age NOT IN (20, 30, NULL);
由于 NULL 在 IN 语句中会返回 UNKNOWN,整个 NOT IN 变成 UNKNOWN,最终不会返回任何数据。
解决方法:
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默认排在最前或最后,具体行为取决于数据库: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 的关联列中,则该行不会被匹配:
SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.id;
如果 orders.customer_id 是 NULL,= NULL 结果是 UNKNOWN,导致 INNER JOIN 失败。
LEFT JOIN 可以保留 orders 但 customers 数据为 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;
总结(重点)
- 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() 等函数可以避免 NULL 带来的问题。
到此这篇关于SQL中三值逻辑和NULL的具体哟使用的文章就介绍到这了,更多相关SQL 三值逻辑和NULL内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
