和NULL打交道的场景特别多:从报表里处理缺失数据到过滤和排序。如果让你在表里留空和用个奇怪的数字比如9999之间选,大多数人肯定选NULL——是的,虽然不太方便,但至少很实在。来看看几个典型的例子。
例子:排序时商品价格缺失
假设我们在运营一个网店,有一个商品表:
| product_id | name | price |
|---|---|---|
| 1 | 手机 | 45000 |
| 2 | 笔记本 | NULL |
| 3 | 相机 | 25000 |
| 4 | 智能手表 | NULL |
我们想按价格排序商品,价格缺失(NULL)的商品要排在最后。
SELECT product_id, name, price
FROM products
ORDER BY price ASC NULLS LAST;
结果:
| product_id | name | price |
|---|---|---|
| 3 | 相机 | 25000 |
| 1 | 手机 | 45000 |
| 2 | 笔记本 | NULL |
| 4 | 智能手表 | NULL |
注意NULLS LAST这个关键字。默认PostgreSQL在ASC排序时会把NULL放前面,加了这个参数就能把它们放到最后。
例子:筛选没有出生日期的学生
我们有个学生表,想查出没有填写出生日期的学生。
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
查询:
SELECT student_id, name
FROM students
WHERE birth_date IS NULL;
结果:
| student_id | name |
|---|---|
| 2 | Anna Song |
| 4 | Maria Chi |
我们成功查出了出生日期未知的学生信息。
处理NULL的函数用法例子
例子:计算总金额时考虑可能的NULL
订单表里存着订单金额。但有些数据没填,这时候我们要把金额当成0来算。
数据示例:
| order_id | customer_name | order_amount |
|---|---|---|
| 1 | Alex | 1200 |
| 2 | Maria | 2500 |
| 3 | Max | NULL |
| 4 | Xena | 3100 |
查询:
SELECT SUM(COALESCE(order_amount, 0)) AS total_amount
FROM orders;
结果:
| total_amount |
|---|
| 6800 |
我们用COALESCE(order_amount, 0)把NULL替换成0再求和,这样就不会出错或者算错了。
例子:用文本替换NULL
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
在报表里,所有空数据要显示成“未填写”而不是NULL。
SELECT
customer_name,
COALESCE(order_amount::TEXT, '未填写') AS order_status
FROM orders;
结果:
| customer_name | order_status |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | 未填写 |
| Xena | 3100 |
COALESCE()可以让你在NULL时显示你想要的文本。
复杂场景下的NULL处理
| customer_name | order_amount |
|---|---|
| Alex | 1200 |
| Maria | 2500 |
| Max | NULL |
| Xena | 3100 |
我们的目标是把缺失金额的订单排在最前面,然后剩下的按金额从大到小排。
SELECT customer_name, order_amount
FROM orders
ORDER BY order_amount DESC NULLS FIRST;
结果:
| customer_name | order_amount |
|---|---|
| Max | NULL |
| Xena | 3100 |
| Maria | 2500 |
| Alex | 1200 |
这里我们用了NULLS FIRST,让NULL排在最前面。
例子:过滤数据并替换NULL值
| student_id | name | birth_date |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | NULL |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | NULL |
有些报表只想显示有数据的行,或者把NULL替换成“未知”。
SELECT
student_id,
name,
COALESCE(birth_date::TEXT, '未知') AS birth_date_info
FROM students;
结果:
| student_id | name | birth_date_info |
|---|---|---|
| 1 | Otto Art | 2000-01-15 |
| 2 | Anna Song | 未知 |
| 3 | Alex Lin | 1999-05-10 |
| 4 | Maria Chi | 未知 |
这个在做报表时特别有用,可以清楚地告诉大家数据缺失。
实用建议
和NULL打交道要格外小心。这里有几个小贴士:
- 用
IS NULL和COALESCE()来检查和替换缺失值。 - 记住聚合函数会忽略
NULL,除了COUNT(*)。 - 排序时记得用
NULLS FIRST和NULLS LAST。 - 在报表里一定要说明你怎么处理
NULL,这样同事才不会误会。
这些知识不仅能帮你写出靠谱的SQL,还能让你面试时加分。毕竟,能搞定真实数据比只会理论更值钱!
GO TO FULL VERSION