美团大数据面试SQL-每个品类销售额的环比增长率
⚠️ 待修正
一、题目背景
这道题来自美团的数据分析岗面试。美团是本地生活服务(外卖、到店、酒旅),数据分析师需要从海量业务数据中挖掘洞见。
业务场景:用户消费行为相关需求在日常工作中频繁出现,这类型的SQL题是面试高频考点。
一、题目
现有一张品类月度销售额表 t6_category_monthly_sales,记录了每个品类的月度销售额。请计算每个品类销售额的环比增长率。
环比增长率 = (本月销售额 - 上月销售额) / 上月销售额 × 100%
品类月度销售额表 t6_category_monthly_sales:
+-------------+---------+-----------+
| category_id | month | sales_amt |
+-------------+---------+-----------+
| C001 | 2023-01 | 100000 |
| C001 | 2023-02 | 120000 |
| C001 | 2023-03 | 108000 |
| C002 | 2023-01 | 80000 |
| C002 | 2023-02 | 95000 |
| C002 | 2023-03 | 110000 |
| C003 | 2023-01 | 50000 |
| C003 | 2023-02 | 48000 |
| C003 | 2023-03 | 52000 |
+-------------+---------+-----------+
三、思路分析
环比增长率是业务分析中最常用的指标之一,使用 LAG 窗口函数获取上期数据即可轻松实现。
解题步骤:
- 按品类分区、按月份排序,使用 LAG 获取上月销售额;
- 按公式计算环比增长率;
- 处理首月数据(上月为NULL时环比增长率也为NULL);
| 维度 | 评分 |
|---|---|
| 题目难度 | ⭐️⭐️ |
| 题目清晰度 | ⭐️⭐️⭐️⭐️⭐️ |
| 业务常见度 | ⭐️⭐️⭐️⭐️⭐️ |
四、逐步推导
1. 使用LAG获取上月销售额
执行SQL
select category_id,
month,
sales_amt,
lag(sales_amt, 1) over (partition by category_id order by month) as prev_sales_amt
from t6_category_monthly_sales
执行结果
+-------------+---------+-----------+----------------+
| category_id | month | sales_amt | prev_sales_amt |
+-------------+---------+-----------+----------------+
| C001 | 2023-01 | 100000 | NULL |
| C001 | 2023-02 | 120000 | 100000 |
| C001 | 2023-03 | 108000 | 120000 |
| C002 | 2023-01 | 80000 | NULL |
| C002 | 2023-02 | 95000 | 80000 |
| C002 | 2023-03 | 110000 | 95000 |
| C003 | 2023-01 | 50000 | NULL |
| C003 | 2023-02 | 48000 | 50000 |
| C003 | 2023-03 | 52000 | 48000 |
+-------------+---------+-----------+----------------+
2. 计算环比增长率
执行SQL
select category_id,
month,
sales_amt,
prev_sales_amt,
case
when prev_sales_amt is not null
then concat(round((sales_amt - prev_sales_amt) / prev_sales_amt * 100, 2), '%')
else null
end as mom_growth_rate
from (
select category_id,
month,
sales_amt,
lag(sales_amt, 1) over (partition by category_id order by month) as prev_sales_amt
from t6_category_monthly_sales
) t
order by category_id, month
执行结果
+-------------+---------+-----------+----------------+-----------------+
| category_id | month | sales_amt | prev_sales_amt | mom_growth_rate |
+-------------+---------+-----------+----------------+-----------------+
| C001 | 2023-01 | 100000 | NULL | NULL |
| C001 | 2023-02 | 120000 | 100000 | 20.00% |
| C001 | 2023-03 | 108000 | 120000 | -10.00% |
| C002 | 2023-01 | 80000 | NULL | NULL |
| C002 | 2023-02 | 95000 | 80000 | 18.75% |
| C002 | 2023-03 | 110000 | 95000 | 15.79% |
| C003 | 2023-01 | 50000 | NULL | NULL |
| C003 | 2023-02 | 48000 | 50000 | -4.00% |
| C003 | 2023-03 | 52000 | 48000 | 8.33% |
+-------------+---------+-----------+----------------+-----------------+
C001在2月增长20%后,3月回落10%;C002持续增长;C003在2月下跌后3月恢复正常。
五、常见坑点
坑1:分子分母的业务定义 — 明确分子是"延迟订单数"还是"延迟用户数",分母对应"总订单数"还是"总用户数",口径不同结果差异大。
坑2:时间差计算的单位 — unix_timestamp 返回秒,除以60才是分钟。忘记单位转换会导致判断完全错误。
六、举一反三
-
按骑手/站点/城市维度下钻:定位问题来源,是某个骑手还是某个区域的延迟率偏高
-
按延迟程度分级:CASE WHEN 分为轻微/中等/严重三级,关注严重延迟的占比
-
时段分析:按小时统计,识别午晚高峰时段的配送压力变化
七、知识点总结
| 考点 | 说明 |
|---|---|
| LAG / LEAD | 获取前/后一行数据,用于环比计算、状态变更检测 |
| NULL值处理 | NULL在聚合和窗口函数中的差异,COALESCE/NVL的替代方案 |
八、建表语句和数据插入
点击展开 DDL & DML
-- 建表语句
CREATE TABLE t6_category_monthly_sales (
category_id string COMMENT '品类ID',
month string COMMENT '月份',
sales_amt decimal(12,2) COMMENT '销售额'
) COMMENT '品类月度销售额表';
-- 数据插入
INSERT INTO t6_category_monthly_sales VALUES
('C001', '2023-01', 100000),
('C001', '2023-02', 120000),
('C001', '2023-03', 108000),
('C002', '2023-01', 80000),
('C002', '2023-02', 95000),
('C002', '2023-03', 110000),
('C003', '2023-01', 50000),
('C003', '2023-02', 48000),
('C003', '2023-03', 52000);
📱关注公众号
「数据仓库技术」文章同步更新,不错过每一篇干货

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