SQL 面试经典:如何用 CASE WHEN 实现分组统计?
在 SQL 面试和日常业务场景中,经常会遇到这样的需求:
统计不同条件下的用户数量;
按性别统计人数;
统计某一列数据在不同区间的分布情况。
这种时候,CASE WHEN 就是最常见、最灵活的写法。本文就带你搞懂 CASE WHEN + 聚合函数 的套路。
1. CASE WHEN 的基本语法
CASE WHEN 在 SQL 中就像 if-else 分支,根据条件返回不同结果。
基本语法:
CASE
WHEN 条件1 THEN 值1
WHEN 条件2 THEN 值2
ELSE 默认值
END
这个结构可以放在 SELECT、WHERE、ORDER BY 甚至 GROUP BY 中。
2. 分组统计的典型场景
假设我们有一张用户表 users,字段包含:
● id:用户ID
● gender:性别(M 表示男,F 表示女)
● age:年龄
● created_at:注册时间
需求 1:统计男女用户数
如果用 GROUP BY,写法是:
SELECT gender, COUNT(*) AS user_count
FROM users
GROUP BY gender;
但如果要在一行结果里直接显示男女数量,就需要用 CASE WHEN:
SELECT
COUNT(CASE WHEN gender = 'M' THEN 1 END) AS male_count,
COUNT(CASE WHEN gender = 'F' THEN 1 END) AS female_count
FROM users;
好处:结果更直观,一次查询就能得到所有统计。
需求 2:统计年龄区间用户数
比如要统计:
● 18 岁以下用户数;
● 18-30 岁用户数;
● 30 岁以上用户数。
写法如下:
SELECT
COUNT(CASE WHEN age < 18 THEN 1 END) AS under_18,
COUNT(CASE WHEN age BETWEEN 18 AND 30 THEN 1 END) AS between_18_30,
COUNT(CASE WHEN age > 30 THEN 1 END) AS above_30
FROM users;
这种写法非常适合做数据分析报表。
需求 3:统计近 7 天与 30 天注册用户
SELECT
COUNT(CASE WHEN created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY) THEN 1 END) AS last_7_days,
COUNT(CASE WHEN created_at >= DATE_SUB(NOW(), INTERVAL 30 DAY) THEN 1 END) AS last_30_days
FROM users;
这种写法在面试中非常高频,考察你是否能灵活运用 CASE WHEN 和日期函数。
3. CASE WHEN 搭配 SUM 的写法
除了 COUNT,CASE WHEN 也常和 SUM 搭配。
例如:统计男女用户的充值金额:
SELECT
SUM(CASE WHEN gender = 'M' THEN amount ELSE 0 END) AS male_amount,
SUM(CASE WHEN gender = 'F' THEN amount ELSE 0 END) AS female_amount
FROM payments;
和 COUNT 不同的是,这里必须给出 ELSE 0,否则 NULL 会影响结果。
4. 面试延伸问题
在面试里,考官可能会进一步追问:
Q1:能否用一条 SQL 统计男女用户数占比?
SELECT
COUNT(CASE WHEN gender = 'M' THEN 1 END) * 1.0 / COUNT(*) AS male_ratio,
COUNT(CASE WHEN gender = 'F' THEN 1 END) * 1.0 / COUNT(*) AS female_ratio
FROM users;
注意:这里乘以 1.0 是为了避免整除,保证结果是小数。
Q2:如果有未知性别怎么办?
SELECT
COUNT(CASE WHEN gender = 'M' THEN 1 END) AS male_count,
COUNT(CASE WHEN gender = 'F' THEN 1 END) AS female_count,
COUNT(CASE WHEN gender IS NULL OR gender NOT IN ('M','F') THEN 1 END) AS unknown_count
FROM users;
这类场景考察你是否能考虑边界情况。
5. 总结
1. CASE WHEN 是 SQL 里的 条件分支,非常灵活。
2. 常见用法:
COUNT(CASE WHEN ... THEN 1 END) → 条件计数
SUM(CASE WHEN ... THEN 值 ELSE 0 END) → 条件求和
3. 在面试和报表开发中,CASE WHEN + 聚合函数经常用来实现 分组统计。
4. 一句话记忆:“GROUP BY 是行分组,CASE WHEN 是列拆分。”
✅ 掌握 CASE WHEN,你就能在面试和实战里写出更灵活的数据统计 SQL。