|
在SQL中,三值逻辑是一个重要概念,它的存在主要是由于 NULL 值的引入。NULL 代表未知值,它既不是空字符串,也不是数字 0,而是一个特殊的标记,表示数据缺失或不可用。
在SQL中,由于NULL值的存在,导致它使用了一种特殊的逻辑作用法:三值逻辑 (Three-Valued Logic, 3VL)
其包括三个任何逻辑计算的可能结果:
TRUE (真) FALSE (假) UNKNOWN (未知)
NULL在SQL中表示“未知”或“缺失的值”,它与普通的值有很大区别。由于NULL表示未知值,所以任何与NULL进行运算的结果都应该是UNKNOWN,而不是TRUE或FALSE。
NULL的特性
NULL并不是一个具体值,而是一个特殊状态,其具有如下特性:
如果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 中
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
总结(重点)
- 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 带来的问题。
|