PostgreSQL NULL 值详解
在 PostgreSQL 中,NULL 代表 未知值或缺失值,而不是空字符串 ('') 或 0。在数据库操作中,NULL 需要特殊处理,因为它的行为与普通值不同。
1. NULL 的基本概念
NULL不是 一个具体的值,而是“没有值”。- 不能用
=或!=比较NULL,需要使用IS NULL或IS NOT NULL进行判断。
示例
SELECT NULL = NULL; -- 结果:NULL(不是 TRUE 也不是 FALSE)
SELECT NULL <> NULL; -- 结果:NULL
SELECT NULL IS NULL; -- 结果:TRUE
SELECT NULL IS NOT NULL; -- 结果:FALSE
2. 在表中使用 NULL
创建包含 NULL 值的表:
CREATE TABLE students (
id SERIAL PRIMARY KEY,
name VARCHAR(100),
age INTEGER
);
插入数据:
INSERT INTO students (name, age) VALUES ('Alice', 20);
INSERT INTO students (name, age) VALUES ('Bob', NULL);
INSERT INTO students (name, age) VALUES ('Charlie', 25);
查询包含 NULL 的数据:
SELECT * FROM students;
结果:
| id | name | age |
|---|---|---|
| 1 | Alice | 20 |
| 2 | Bob | NULL |
| 3 | Charlie | 25 |
3. NULL 的比较与判断
(1) IS NULL / IS NOT NULL
用来检查 NULL 值:
SELECT * FROM students WHERE age IS NULL;
结果:
| id | name | age |
|---|---|---|
| 2 | Bob | NULL |
如果想查询 非 NULL 的值:
SELECT * FROM students WHERE age IS NOT NULL;
(2) COALESCE()
COALESCE() 函数用于 替换 NULL 值,返回第一个非 NULL 值:
SELECT name, COALESCE(age, 18) AS age FROM students;
结果:
| name | age |
|---|---|
| Alice | 20 |
| Bob | 18 |
| Charlie | 25 |
(3) NULLIF()
NULLIF(value1, value2):如果 value1 = value2,返回 NULL,否则返回 value1。
SELECT NULLIF(10, 10); -- 结果:NULL
SELECT NULLIF(10, 20); -- 结果:10
4. NULL 在计算中的影响
NULL参与计算时,结果仍为NULL。
SELECT 10 + NULL; -- 结果:NULL
SELECT NULL * 5; -- 结果:NULL
- 使用
COALESCE()避免 NULL 影响计算:
SELECT name, COALESCE(age, 0) * 2 AS double_age FROM students;
5. NULL 在聚合函数中的影响
COUNT(*)计算所有行,包括NULL值。COUNT(column)不计算NULL值。
SELECT COUNT(*) FROM students; -- 结果:3
SELECT COUNT(age) FROM students; -- 结果:2
- 其他聚合函数如
SUM()、AVG()、MIN()、MAX()也会忽略NULL值:
SELECT AVG(age) FROM students; -- 结果:(20+25)/2 = 22.5
SELECT SUM(age) FROM students; -- 结果:45
6. NULL 在 ORDER BY 排序中的影响
默认情况下,NULL 值在 ORDER BY ASC 时排在最后,在 ORDER BY DESC 时排在最前:
SELECT * FROM students ORDER BY age ASC;
如果想让 NULL 值排在最前,可以使用 NULLS FIRST:
SELECT * FROM students ORDER BY age ASC NULLS FIRST;
7. NULL 在 JOIN 查询中的影响
在 JOIN 操作中,NULL 可能会影响匹配:
CREATE TABLE courses (
student_name VARCHAR(100),
course VARCHAR(50)
);
INSERT INTO courses VALUES ('Alice', 'Math'), ('Charlie', 'Physics');
SELECT students.name, students.age, courses.course
FROM students
LEFT JOIN courses ON students.name = courses.student_name;
结果:
| name | age | course |
|---|---|---|
| Alice | 20 | Math |
| Bob | NULL | NULL |
| Charlie | 25 | Physics |
8. NULL 在 CHECK 约束中的处理
创建表时可以使用 CHECK 限制 NULL 处理:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary INTEGER CHECK (salary > 0)
);
如果 salary 插入 NULL,不会触发 CHECK 约束,因为 NULL 不是 > 0 也不是 <= 0。
要避免这种情况,需要 salary 设置 NOT NULL:
CREATE TABLE employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
salary INTEGER NOT NULL CHECK (salary > 0)
);
9. 处理 NULL 的最佳实践
- 使用
COALESCE()替换NULL,避免NULL影响计算。 - 使用
IS NULL/IS NOT NULL进行判断,不要用=。 - 在
ORDER BY时注意NULL的排序规则。 - 在
JOIN查询中要考虑NULL可能影响匹配结果。 - 在
CHECK约束中要注意NULL的特殊情况。
更多详细内容请关注其他相关文章!