首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >字节跳动大数据面试SQL-每月销售额与上月的同比环比

字节跳动大数据面试SQL-每月销售额与上月的同比环比

作者头像
数据仓库晨曦
发布于 2026-06-29 12:34:04
发布于 2026-06-29 12:34:04
2960
举报
文章被收录于专栏:数据仓库技术数据仓库技术

一、题目背景

这道题来自字节跳动电商业务的数据分析岗面试。环比和同比是数据分析中最基础的指标,但 SQL 面试中很多人因为 LAG 函数用不熟而翻车。

业务场景:月度经营分析会上,GMV 报表必须包含"环比增长"和"同比增长"两列。环比看短期趋势(这个月比上个月好还是差),同比消除季节因素(今年1月跟去年1月比)。

二、题目

现有一张月度销售汇总表 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%

期望输出:每个月的销售额、环比增长率(%)、同比增长率(%)。

三、思路分析

  1. 环比:LAG(sales, 1) 取上一行(上个月),适用于时间序列有序数据
  2. 同比:LAG(sales, 12) 取 12 行前(去年同月),前提是数据按月连续排列
  3. 如果数据有缺失月份,同比用 LEFT JOIN 更安全

维度

评分

题目难度

⭐️⭐️

题目清晰度

⭐️⭐️⭐️⭐️⭐️

业务常见度

⭐️⭐️⭐️⭐️⭐️

四、逐步推导

步骤1:环比

Spark SQL

代码语言:javascript
复制
SELECT
    month,
    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_pct
FROM t15_zj_monthly_sales
ORDERBYmonth;
代码语言: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
复制
SELECT
    month,
    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_pct
FROM t15_zj_monthly_sales
ORDERBYmonth;

执行结果

代码语言: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
复制
SELECT
    month,
    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_pct
FROM t15_zj_monthly_sales
ORDERBYmonth;

最终结果(完整数据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) 兜底。

六、举一反三

  1. 累计同比:SUM(sales) OVER (ORDER BY month ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) 计算滚动12个月的累计销售额
  2. 移动平均: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,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 一、题目背景
  • 二、题目
  • 三、思路分析
  • 四、逐步推导
    • 步骤1:环比
    • 步骤2:同比
    • 步骤3:合并环比和同比
  • 五、常见坑点
  • 六、举一反三
  • 七、知识点总结
  • 八、建表语句和数据插入
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档