在用户数据分析场景中,按年龄段统计用户分布是高频需求,通过SQL的CASE WHEN条件判断结合GROUP BY分组功能,可以高效完成这类统计任务,不需要额外在应用层做复杂处理。
实现思路说明
核心逻辑分为两步,第一步是用CASE_WHEN语句给每个用户匹配对应的年龄段标签,第二步是用GROUP_BY对年龄段标签进行分组,再统计每个组的用户数量。首先需要明确年龄段的划分规则,比如常见的划分方式是0-18岁为未成年,19-30岁为青年,31-50岁为中年,51岁及以上为老年,也可以根据业务需求自定义划分区间。
基础表结构示例
假设我们有一个用户基础信息表user_info,表结构如下:
| 字段名 | 类型 | 说明 |
|---|---|---|
| user_id | int | 用户唯一ID |
| user_name | varchar(50) | 用户姓名 |
| age | int | 用户年龄 |
完整查询语句实现
按照上述年龄段划分规则,完整的统计查询语句如下:
-- 按年龄段统计用户数量
SELECT
CASE
WHEN age <= 18 THEN '0-18岁'
WHEN age >= 19 AND age <= 30 THEN '19-30岁'
WHEN age >= 31 AND age <= 50 THEN '31-50岁'
ELSE '51岁及以上'
END AS age_group,
COUNT(user_id) AS user_count
FROM user_info
WHERE age IS NOT NULL -- 过滤年龄为空的异常数据
GROUP BY age_group
ORDER BY
CASE age_group
WHEN '0-18岁' THEN 1
WHEN '19-30岁' THEN 2
WHEN '31-50岁' THEN 3
ELSE 4
END;
代码逻辑解析
上述查询语句的执行逻辑如下:
CASE WHEN部分会逐行判断每个用户的age值,匹配到对应的条件后返回对应的年龄段标签,赋值给age_group字段。COUNT(user_id)用于统计每个年龄段下的用户数量,使用user_id统计可以避免重复计数,前提是user_id是唯一非空字段。WHERE age IS NOT NULL是可选的过滤条件,用于排除年龄字段为空的异常用户数据,避免统计结果偏差。- 最后的
ORDER BY子句通过嵌套CASE WHEN,让统计结果按照年龄段的顺序从小到大排列,更符合阅读习惯。
注意事项
实际使用中需要注意几个细节:
- 年龄段划分的区间边界要清晰,避免同一个年龄匹配到多个条件,比如不要同时写
age <= 30和age >= 30,会导致30岁的用户匹配到两个标签。 - 如果
age字段存在负数或者超过合理范围的值,建议先通过WHERE条件过滤掉这些异常数据,比如增加age > 0 AND age < 120的条件。 - 如果统计的用户表数据量很大,可以在
age字段上建立索引,提升CASE WHEN判断的执行效率。
扩展场景示例
如果需要同时统计每个年龄段的用户占比,可以在上述查询的基础上做扩展:
-- 统计每个年龄段的用户数量和占比
SELECT
age_group,
user_count,
CONCAT(ROUND(user_count / total_count * 100, 2), '%') AS user_ratio
FROM (
SELECT
CASE
WHEN age <= 18 THEN '0-18岁'
WHEN age >= 19 AND age <= 30 THEN '19-30岁'
WHEN age >= 31 AND age <= 50 THEN '31-50岁'
ELSE '51岁及以上'
END AS age_group,
COUNT(user_id) AS user_count,
(SELECT COUNT(user_id) FROM user_info WHERE age IS NOT NULL) AS total_count
FROM user_info
WHERE age IS NOT NULL
GROUP BY age_group
) AS temp
ORDER BY
CASE age_group
WHEN '0-18岁' THEN 1
WHEN '19-30岁' THEN 2
WHEN '31-50岁' THEN 3
ELSE 4
END;
这个扩展查询通过子查询先获取总有效用户数,再计算每个年龄段的用户占比,返回的结果包含年龄段、用户数量、用户占比三个字段,满足更丰富的统计需求。