字节跳动大数据面试SQL-每月销售额与上月的同比环比
一、题目背景
这道题来自字节跳动电商业务的数据分析岗面试。环比和同比是数据分析中最基础的指标,但 SQL 面试中很多人因为 LAG 函数用不熟而翻车。
二、题目
现有一张月度销售汇总表 t15_zj_monthly_sales。请计算每个月的环比增长率和同比增长率。
t15_zj_monthly_sales 表
代码语言:javascript复制 ---------- -------- |month | sales| ---------- -------- | 2024-01| 10000|| 2024-02| 12000|| 2024-03| 11000|| 2024-04| 13000|| 2024-05| 14000|| 2024-06| 15000|| 2024-07| 16000|| 2024-08| 15500|| 2024-09| 14500|| 2024-10| 15000|| 2024-11| 17000|| 2024-12| 20000|| 2025-01| 15000|| 2025-02| 18000|| 2025-03| 16000| ---------- --------
定义:
环比 = (本月 - 上月) / 上月 × 100%同比 = (本月 - 去年同月) / 去年同月 × 100%期望输出:每个月的销售额、环比增长率(%)、同比增长率(%)。
三、思路分析
环比:LAG(sales, 1) 取上一行(上个月),适用于时间序列有序数据同比:LAG(sales, 12) 取 12 行前(去年同月),前提是数据按月连续排列如果数据有缺失月份,同比用 LEFT JOIN 更安全维度 | 评分 |
|---|---|
题目难度 | ⭐️⭐️ |
题目清晰度 | ⭐️⭐️⭐️⭐️⭐️ |
业务常见度 | ⭐️⭐️⭐️⭐️⭐️ |
四、逐步推导
步骤1:环比
Spark SQL
代码语言:javascript复制SELECTmonth,sales,LAG(sales, 1) OVER (ORDERBYmonth) AS prev_month_sales,ROUND((sales - LAG(sales, 1) OVER (ORDERBYmonth)) * 100.0/ LAG(sales, 1) OVER (ORDERBYmonth), 1) AS mom_pctFROM t15_zj_monthly_salesORDERBYmonth;代码语言:javascript复制
---------- -------- ------------------- ---------- |month | sales| prev_month_sales| mom_pct| ---------- -------- ------------------- ---------- | 2024-01| 10000| NULL| NULL || 2024-02| 12000| 10000 | 20.0 || 2024-03| 11000| 12000 | -8.3 || 2024-04| 13000| 11000 | 18.2 || 2024-05| 14000| 13000 | 7.7|| 2024-06| 15000| 14000 | 7.1|| 2024-07| 16000| 15000 | 6.7|| 2024-08| 15500| 16000 | -3.1 || 2024-09| 14500| 15500 | -6.5 || 2024-10| 15000| 14500 | 3.4|| 2024-11| 17000| 15000 | 13.3 || 2024-12| 20000| 17000 | 17.6 || 2025-01| 15000| 20000 | -25.0|| 2025-02| 18000| 15000 | 20.0 || 2025-03| 16000| 18000 | -11.1| ---------- -------- ------------------- ---------- 15 rows selected (0.905 seconds)(https://www.dwsql.com)
第一行没有上月数据,环比为 NULL。
步骤2:同比
Spark SQL
代码语言:javascript复制SELECTmonth,sales,LAG(sales, 12) OVER (ORDERBYmonth) AS last_year_sales,ROUND((sales - LAG(sales, 12) OVER (ORDERBYmonth)) * 100.0/ LAG(sales, 12) OVER (ORDERBYmonth), 1) AS yoy_pctFROM t15_zj_monthly_salesORDERBYmonth;
执行结果
代码语言:javascript复制 ---------- -------- ------------------ ---------- |month | sales| last_year_sales| yoy_pct| ---------- -------- ------------------ ---------- | 2024-01| 10000| NULL | NULL || 2024-02| 12000| NULL | NULL || 2024-03| 11000| NULL | NULL || 2024-04| 13000| NULL | NULL || 2024-05| 14000| NULL | NULL || 2024-06| 15000| NULL | NULL || 2024-07| 16000| NULL | NULL || 2024-08| 15500| NULL | NULL || 2024-09| 14500| NULL | NULL || 2024-10| 15000| NULL | NULL || 2024-11| 17000| NULL | NULL || 2024-12| 20000| NULL | NULL || 2025-01| 15000| 10000| 50.0 || 2025-02| 18000| 12000| 50.0 || 2025-03| 16000| 11000| 45.5 | ---------- -------- ------------------ ---------- 15 rows selected (0.267 seconds)(https://www.dwsql.com)
24年数据为空,因为24年没有上一年的数据
步骤3:合并环比和同比
Spark SQL
代码语言:javascript复制SELECTmonth,sales,ROUND((sales - LAG(sales, 1) OVER (ORDERBYmonth)) * 100.0/ LAG(sales, 1) OVER (ORDERBYmonth), 1) AS mom_pct,ROUND((sales - LAG(sales, 12) OVER (ORDERBYmonth)) * 100.0/ LAG(sales, 12) OVER (ORDERBYmonth), 1) AS yoy_pctFROM t15_zj_monthly_salesORDERBYmonth;
最终结果(完整数据25行,截取关键月份):
代码语言:javascript复制 ---------- -------- ---------- ---------- |month | sales| mom_pct| yoy_pct| ---------- -------- ---------- ---------- | 2024-01| 10000| NULL | NULL || 2024-02| 12000| 20.0 | NULL || 2024-03| 11000| -8.3 | NULL || 2024-04| 13000| 18.2 | NULL || 2024-05| 14000| 7.7| NULL || 2024-06| 15000| 7.1| NULL || 2024-07| 16000| 6.7| NULL || 2024-08| 15500| -3.1 | NULL || 2024-09| 14500| -6.5 | NULL || 2024-10| 15000| 3.4| NULL || 2024-11| 17000| 13.3 | NULL || 2024-12| 20000| 17.6 | NULL || 2025-01| 15000| -25.0| 50.0 || 2025-02| 18000| 20.0 | 50.0 || 2025-03| 16000| -11.1| 45.5 | ---------- -------- ---------- ---------- 15 rows selected (0.325 seconds)(https://www.dwsql.com)
2025-01 的同比增长 50%(15000 vs 10000),增长显著。
五、常见坑点
坑1:LAG 依赖排序
如果表不按时间排序,LAG 取到的是随机行。必须 ORDER BY month。
坑2:缺失月份导致同比错位
如果 2024-07 数据缺失,LAG(sales, 12) 对 2025-07 取到的是 2024-06 而非 2024-07,同比完全错误!数据有缺失时必须用 LEFT JOIN 方案替代 LAG。
坑3:分母为零
如果上个月销售额为 0,除法会报错。加 NULLIF(LAG(sales) OVER w, 0) 兜底。
六、举一反三
累计同比:SUM(sales) OVER (ORDER BY month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) 计算滚动12个月的累计销售额移动平均:AVG(sales) OVER (ORDER BY month ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) 3个月移动平均,平滑波动七、知识点总结
考点 | 说明 |
|---|---|
LAG(sales, 1) | 取上一行 = 环比 |
LAG(sales, 12) | 取12行前 = 同比(连续数据) |
数据缺失 | 用 LEFT JOIN 替代 LAG 保证准确性 |
八、建表语句和数据插入
代码语言:javascript复制CREATE TABLE IF NOT EXISTS t15_zj_monthly_sales (month STRING, sales BIGINT);INSERT INTO t15_zj_monthly_sales VALUES('2024-01',10000),('2024-02',12000),('2024-03',11000),('2024-04',13000),('2024-05',14000),('2024-06',15000),('2024-07',16000),('2024-08',15500),('2024-09',14500),('2024-10',15000),('2024-11',17000),('2024-12',20000),('2025-01',15000),('2025-02',18000),('2025-03',16000);本文参与腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2026-06-21,如有侵权请联系[email protected] 删除
-
06.30
QQ三国八阵图行走指南:详细路线攻略介绍
-
06.30
原神叶洛亚装备怎样搭配
-
06.30
《天涯明月刀》紫色锦鲤任务化险为夷流程攻略
-
06.30
海域重启武器推荐 海域重启高性价比武器选择攻略
-
06.30
龙岛异兽起源极寒冻土探索指南:深度解析异兽诞生背景与冻土生态秘密
-
06.30
苍蓝前线怎样高效升级
-
- 黑客帝国里讲的是否真的会发生
- 06.30
-
- 企业品牌步入AI可见性诊断阶段
- 06.30
-
-
-
-
下载
- 《神剑伏魔录》(神剑风云)游戏音乐合集
- 其他游戏|7.73 MB
- 一款非常好玩的武侠闯关游戏
-
-
下载
- 《行尸走肉第一章》免安装中文汉化硬盘版下载
- 单机|436 MB
- 一款以动作冒险为主题的游戏
-
-
下载
- 《街头霸王X铁拳》免安装中文汉化硬盘版下载
- 单机|111MB
- 一款非常好玩的格斗游戏
-
-
下载
- 《生化危机:浣熊市行动》免安装中文硬盘版下载
- 单机|6310 MB
- 一款以动作射击为主题的游戏
-
-
下载
- 《暗黑破坏神3》免安装繁体中文正式版下载
- 单机|7630 MB
- 一款以角色扮演为主题的游戏
-
-
下载
- 《马克思佩恩3》免安装硬盘版下载
- 单机|27033 MB
- 一款以第三人称射击为主题的游戏