跳到主要内容

蚂蚁集团大数据面试SQL-芝麻信用分人群分布

⚠️ 待修正

一、题目背景

这道题来自蚂蚁集团芝麻信用事业部的数据分析岗面试。芝麻信用分是支付宝生态的核心风控和用户分层工具,涵盖350-950分共五个等级。数据分析师需要通过信用分分布了解用户质量结构,为信贷额度、免押金服务等业务决策提供数据支持。

业务场景:运营团队每月要出一份"信用分人群分布报告",看各等级用户占比的变化趋势。如果"较差"人群占比突然上升,需要联动风控团队排查是否有刷分行为。

二、题目

现有一张用户芝麻信用分表 t1_zhima_score,包含用户ID和芝麻信用分。请按以下区间统计各人群的用户数和占比:

区间人群标签
350-500较差
501-600中等
601-700良好
701-800优秀
801-950极好

芝麻信用分表 t1_zhima_score:

+----------+--------+
| user_id | score |
+----------+--------+
| u01 | 680 |
| u02 | 720 |
| u03 | 550 |
| u04 | 810 |
| u05 | 420 |
| u06 | 760 |
| u07 | 630 |
| u08 | 580 |
| u09 | 880 |
| u10 | 490 |
+----------+--------+

三、思路分析

本题考察 CASE WHEN 分段统计和占比计算:

  1. 分段映射:用 CASE WHEN 将信用分映射到对应的区间标签
  2. 分组统计:按区间标签 GROUP BY 统计每组的用户数
  3. 占比计算:用 SUM(COUNT(*)) OVER() 窗口函数获取总人数,各组人数/总人数得占比
维度评分
题目难度⭐️
题目清晰度⭐️⭐️⭐️⭐️⭐️
业务常见度⭐️⭐️⭐️⭐️⭐️

四、逐步推导

步骤1:使用 CASE WHEN 将信用分映射到区间标签

select user_id,
score,
case
when score between 350 and 500 then '350-500(较差)'
when score between 501 and 600 then '501-600(中等)'
when score between 601 and 700 then '601-700(良好)'
when score between 701 and 800 then '701-800(优秀)'
when score between 801 and 950 then '801-950(极好)'
end as score_range
from t1_zhima_score

执行结果

+----------+--------+--------------------+
| user_id | score | score_range |
+----------+--------+--------------------+
| u01 | 680 | 601-700(良好) |
| u02 | 720 | 701-800(优秀) |
| u03 | 550 | 501-600(中等) |
| u04 | 810 | 801-950(极好) |
| u05 | 420 | 350-500(较差) |
| u06 | 760 | 701-800(优秀) |
| u07 | 630 | 601-700(良好) |
| u08 | 580 | 501-600(中等) |
| u09 | 880 | 801-950(极好) |
| u10 | 490 | 350-500(较差) |
+----------+--------+--------------------+

步骤2:统计各区间人数及占比

select score_range,
count(1) as user_cnt,
round(count(1) / sum(count(1)) over (), 4) as user_rate
from (
select case
when score between 350 and 500 then '350-500(较差)'
when score between 501 and 600 then '501-600(中等)'
when score between 601 and 700 then '601-700(良好)'
when score between 701 and 800 then '701-800(优秀)'
when score between 801 and 950 then '801-950(极好)'
end as score_range
from t1_zhima_score
) t
group by score_range
order by score_range

执行结果

+--------------------+----------+-----------+
| score_range | user_cnt | user_rate |
+--------------------+----------+-----------+
| 350-500(较差) | 2 | 0.2000 |
| 501-600(中等) | 2 | 0.2000 |
| 601-700(良好) | 2 | 0.2000 |
| 701-800(优秀) | 2 | 0.2000 |
| 801-950(极好) | 2 | 0.2000 |
+--------------------+----------+-----------+

各信用分区间分布均匀,各占20%。实际业务中通常呈正态分布,"良好"和"中等"区间人数最多。

五、常见坑点

坑1:CASE WHEN 条件的判断顺序

CASE WHEN 按从上到下的顺序匹配,第一个满足的条件生效。如果先写 WHEN score >= 350 再写 WHEN score >= 801,那 801分以上的用户会被第一个条件捕获,不会进入"极好"区间。正确做法是从小到大或从大到小写区间,确保不重叠。

坑2:BETWEEN 的边界是闭区间

BETWEEN 350 AND 500 包含 350 和 500 两个边界值。如果实际分数刚好落在边界(如 500分),需确认业务定义是"350-500"还是"350-499, 500-600"。

坑3:占比用 SUM OVER() 比子查询更简洁

老式写法是在子查询中 SELECT COUNT(*) FROM table 拿到总数再做除法,两次扫描。SUM(COUNT(*)) OVER() 一次扫描搞定,且窗口函数的占比计算不受 GROUP BY 影响。

六、举一反三

  1. 动态分段阈值:如果分段值存在配置表中,用 JOIN 替代硬编码 CASE WHEN,阈值变更时只需改配置表
  2. 累计分布(CDF)SUM(user_cnt) OVER (ORDER BY score_range) 计算按分数从低到高的累计占比
  3. 按月趋势:加上月份维度 GROUP BY month, score_range,观察各等级人群占比的月度变化
  4. 交叉分析:关联用户交易表,统计各信用等级用户的平均客单价、逾期率等,验证信用分的区分度

七、知识点总结

考点说明
CASE WHEN 分段将连续值映射为离散标签,注意条件顺序
GROUP BY + COUNT按标签分组统计用户数
SUM() OVER() 算占比窗口函数一次扫描获取全局总数
ROUND 格式化占比保留4位小数便于展示

八、建表语句和数据插入

点击展开 DDL & DML
CREATE TABLE t1_zhima_score (
user_id string COMMENT '用户ID',
score int COMMENT '芝麻信用分'
) COMMENT '用户芝麻信用分表';

INSERT INTO t1_zhima_score VALUES
('u01', 680), ('u02', 720), ('u03', 550),
('u04', 810), ('u05', 420), ('u06', 760),
('u07', 630), ('u08', 580), ('u09', 880),
('u10', 490);
📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看