环比计算是什么
用 LAG 取上一期的值,与本期相减或相除就得到环比。关键是分区与排序要写全:分区键决定“和谁比”(同一门店、同一品类),排序键决定“跟哪一期比”。任意一个写漏,都会算出看起来合理却完全错误的结果。
基本信息
| 核心写法 | LAG(值) OVER (PARTITION BY 对象 ORDER BY 时间) |
|---|---|
| 分区 | PARTITION BY 业务对象,例如门店、商品 |
| 排序 | ORDER BY 时间,例如月份、日期 |
| 首期处理 | 没有上一期,结果为 NULL,需要单独说明 |
| 除零保护 | 分母用 NULLIF 包住 |
| 时间缺口 | 序列不连续时“上一行”不等于“上一期” |
门店月度环比
门店月度环比
SELECT store_id, month, revenue,
LAG(revenue) OVER (PARTITION BY store_id ORDER BY month) AS prev_revenue,
ROUND(100.0 * (revenue - LAG(revenue) OVER (PARTITION BY store_id ORDER BY month))
/ NULLIF(LAG(revenue) OVER (PARTITION BY store_id ORDER BY month), 0), 2) AS mom_pct
FROM store_monthly
ORDER BY store_id, month;
-- 各门店首行 prev_revenue 为 NULL,环比自然为空
-- 上期为 0 时返回 NULL,而不是报错常见错误与后果
| 写法 | 结果 | 正确做法 |
|---|---|---|
| 漏掉 PARTITION BY | 不同门店互相比较,环比全错 | 按业务对象分区 |
| 漏掉 ORDER BY | 没有“上一期”的定义,结果不确定 | 按时间排序 |
| 月份有缺口 | 和上一条记录比,而不是上一个月 | 先补全月份序列 |
| 未防除零 | 分母为 0 时报错或返回 NULL | 分母套 NULLIF |
| 首期不处理 | 首行显示异常或空白 | 单独过滤或补默认值 |
典型使用场景
- 门店月度营收环比,用于经营分析
- 商品销量周环比,识别增长或下滑趋势
- 接口调用量日环比,用于容量预警
- 用户活跃数环比,评估运营活动效果
- 环比与同比并列展示:环比看短期波动,同比看年度趋势
- 数据校验:环比异常大的值往往是补数或口径变化造成的
补全日期序列是算环比的前提:某个月缺数据时 LAG 会取到更早的月份,环比就成了跨期比较。常见做法是先构造连续月份序列,再左连接业务数据。
环比值域没有上限:上期很小而本期很大时会得到几百甚至几千个百分点的增长,报表直接展示容易误导。必要时同时给出绝对值,或对超过一定幅度的值做标记。