SQL NULL 值 – IS NULL 和 IS NOT NULL(千字长文)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在数据库开发中,NULL 值是一个既基础又容易引发误解的概念。无论是处理用户表的空字段,还是分析业务数据中的缺失信息,开发者都不可避免地会遇到 NULL 值的场景。而 IS NULL 和 IS NOT NULL 是 SQL 语言中用于筛选 NULL 值的两个核心操作符。
本文将通过 循序渐进 的方式,从 NULL 的基本定义、语法用法、实际案例到常见陷阱,逐步解析这两个操作符的使用场景与技巧。无论是编程新手还是有一定经验的开发者,都能通过本文掌握如何高效处理 SQL 中的 NULL 值问题。
一、NULL 值的基本概念:什么是 SQL 中的 NULL?
在 SQL 中,NULL 表示“未知的值”或“不存在的值”,与空字符串(''
)或数值零(0
)完全不同。例如:
- 一个用户注册时未填写邮箱地址,数据库字段中会存储为 NULL;
- 一个订单表中,某个订单尚未分配物流单号,该字段也会显示为 NULL。
NULL 的三个核心特性
- 不可比较性:任何值与 NULL 的比较(如
=
,<>
,>
等)都会返回 NULL,而非布尔值。 - 占位符作用:NULL 表示字段“未被赋值”,而非“值为零”或“空字符串”。
- 类型无关性:NULL 不属于任何数据类型,可以存储在任何类型的字段中。
形象比喻:
可以把 NULL 想象为一张“空白的答题卡”——它既不是正确答案,也不是错误答案,只是未填写的状态。开发者需要通过 IS NULL 或 IS NOT NULL 明确判断这种“空白状态”。
二、IS NULL 和 IS NOT NULL 的语法解析
1. IS NULL 的用法:筛选 NULL 值的记录
语法格式:
SELECT * FROM table_name
WHERE column_name IS NULL;
示例:
假设有一个 employees
表,其中 email
字段可能未被填写:
-- 创建示例表
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
-- 插入数据(部分 email 字段为 NULL)
INSERT INTO employees VALUES
(1, 'Alice', 'alice@example.com'),
(2, 'Bob', NULL),
(3, 'Charlie', 'charlie@example.com');
-- 查询 email 为 NULL 的记录
SELECT * FROM employees
WHERE email IS NULL;
输出结果:
| id | name | email |
|----|--------|----------------|
| 2 | Bob | NULL |
2. IS NOT NULL 的用法:筛选非 NULL 值的记录
语法格式:
SELECT * FROM table_name
WHERE column_name IS NOT NULL;
示例:
-- 查询 email 非 NULL 的记录
SELECT * FROM employees
WHERE email IS NOT NULL;
输出结果:
| id | name | email |
|----|----------|----------------------|
| 1 | Alice | alice@example.com |
| 3 | Charlie | charlie@example.com |
三、实际案例:NULL 值的典型应用场景
案例 1:统计未完成的订单
假设有一个 orders
表,其中 shipping_date
字段表示订单发货时间。若某订单尚未发货,则该字段为 NULL。
-- 查询未发货的订单
SELECT order_id, customer_name
FROM orders
WHERE shipping_date IS NULL;
案例 2:清理无效数据
在数据清洗时,可能需要删除 price
字段为 NULL 的商品记录:
-- 删除 price 为 NULL 的商品
DELETE FROM products
WHERE price IS NULL;
案例 3:条件判断与 NULL
在业务逻辑中,可能需要根据字段是否为 NULL 执行不同操作。例如,只有当 user_status
不为 NULL 时才允许登录:
-- 检查用户是否有效
SELECT * FROM users
WHERE user_status IS NOT NULL AND is_active = 1;
四、常见误区与陷阱:为什么不能用 = NULL
?
误区 1:错误地使用 = NULL
许多开发者会误以为 WHERE column = NULL
可以筛选 NULL 值,但这是错误的!
原因:
由于 NULL 表示“未知值”,任何与 NULL 的比较(如 =
, !=
)都会返回 NULL,而 SQL 中只有 TRUE 才会保留记录。因此:
-- 错误写法
SELECT * FROM employees
WHERE email = NULL; -- 返回空结果
正确写法:
SELECT * FROM employees
WHERE email IS NULL;
误区 2:忽视 NULL 对聚合函数的影响
某些聚合函数(如 SUM
, AVG
)会自动忽略 NULL 值,可能导致意外结果。例如:
-- 假设 `sales` 表中部分 `revenue` 字段为 NULL
SELECT AVG(revenue) FROM sales;
-- 计算时会自动排除 NULL 值,可能低估实际均值
误区 3:在 JOIN
操作中忽略 NULL
当使用 LEFT JOIN
时,若右表字段为 NULL,可能导致条件判断失败。例如:
-- 错误示例:试图匹配 NULL 值
SELECT *
FROM orders
LEFT JOIN customers ON orders.customer_id = customers.id
WHERE customers.name = 'John';
-- 若 customers.name 为 NULL,则条件不成立
五、最佳实践:如何安全地处理 NULL 值?
1. 明确字段是否允许 NULL
在表设计阶段,通过 NOT NULL
约束强制字段必须赋值:
CREATE TABLE users (
id INT PRIMARY KEY,
username VARCHAR(50) NOT NULL, -- 不能为空
bio TEXT -- 允许 NULL
);
2. 使用 COALESCE
替代 NULL
当需要将 NULL 转换为默认值时,使用 COALESCE
函数:
-- 将 NULL 转换为空字符串
SELECT COALESCE(email, '') AS formatted_email
FROM employees;
3. 在条件判断中优先使用 IS NULL
避免混合使用 =
和 IS NULL
,保持代码一致性:
-- 推荐写法
WHERE status IS NULL OR status = 'pending';
-- 避免写法
WHERE status = 'pending' OR status = NULL; -- 错误!
4. 记录 NULL 的业务含义
在文档中明确 NULL 的业务意义,例如:
NULL
在address
字段中表示“未提供地址”;NULL
在end_date
字段中表示“合同尚未终止”。
六、高级技巧:NULL 在复杂查询中的应用
技巧 1:用 CASE
表达式处理 NULL
在需要根据 NULL 值进行逻辑分支时,CASE
表达式非常有用:
SELECT
id,
name,
CASE
WHEN email IS NULL THEN '未设置邮箱'
ELSE email
END AS contact_info
FROM employees;
技巧 2:结合 UNION
处理 NULL 与非 NULL
在需要同时展示 NULL 和非 NULL 记录时,可使用 UNION
分组:
SELECT 'Non-Null' AS type, * FROM employees WHERE email IS NOT NULL
UNION ALL
SELECT 'Null' AS type, * FROM employees WHERE email IS NULL;
技巧 3:在索引中考虑 NULL 值
某些数据库系统(如 PostgreSQL)支持对 NULL 值的索引优化,但需注意:
-- 创建包含 NULL 值的索引
CREATE INDEX idx_email_null ON employees (email NULLS LAST);
结论:掌握 NULL 值是 SQL 开发的基石
SQL NULL 值 – IS NULL 和 IS NOT NULL 是开发者必须熟练掌握的核心技能。通过本文的讲解,读者可以:
- 理解 NULL 的本质及其与其他值的区别;
- 正确使用 IS NULL 和 IS NOT NULL 进行数据筛选;
- 避免常见陷阱,如错误的比较操作或聚合函数的影响;
- 结合业务场景设计更健壮的查询逻辑。
在实际开发中,NULL 值的处理往往隐藏在复杂的业务需求背后。只有通过深入理解其特性,并通过代码实践不断巩固,才能真正提升 SQL 开发的效率与质量。
希望本文能成为你数据库学习旅程中的一个扎实起点!