LAG 窗口函数详解
一、一句话理解
LAG(列, n, 默认值) 从当前行往前数 n 行取值。好比排队时回头看前面那个人的信息。
二、函数语法
LAG(列名, 偏移行数, 默认值) OVER (PARTITION BY 分组列 ORDER BY 排序列)
- 偏移行数默认 1,默认值默认 NULL
- PARTITION BY 可选,分组后每组独立计算
三、真实业务场景
场景:计算每月销售额环比增长率
月销售额表,计算环比 = (本月 - 上月) / 上月。
SELECT month, sales,
LAG(sales, 1) OVER (ORDER BY month) AS prev_month_sales,
ROUND((sales - LAG(sales, 1) OVER (ORDER BY month)) * 100.0
/ LAG(sales, 1) OVER (ORDER BY month), 1) AS mom_pct
FROM monthly_sales
ORDER BY month;
示例数据与结果:
+----------+--------+------------------+---------+
| month | sales | prev_month_sales | mom_pct |
+----------+--------+------------------+---------+
| 2025-01 | 10000 | NULL | NULL |
| 2025-02 | 12000 | 10000 | 20.0 |
| 2025-03 | 11000 | 12000 | -8.3 |
| 2025-04 | 15000 | 11000 | 36.4 |
+----------+--------+------------------+---------+
第一行没有"上一行",LAG 返回 NULL,环比为空。
场景2:检测用户连续登录
找出连续登录的用户——两次登录间隔为1天即为连续。
SELECT user_id, login_date,
LAG(login_date) OVER (PARTITION BY user_id ORDER BY login_date) AS prev_date,
DATEDIFF(login_date, LAG(login_date) OVER (PARTITION BY user_id ORDER BY login_date)) AS gap
FROM user_login;
gap=1 表示连续登录,gap>1 表示中断。
四、与 LEAD 的对比
| 函数 | 方向 | 用途 |
|---|---|---|
| LAG | 看过去 | 环比、与上一行比较 |
| LEAD | 看未来 | 同比、与下一行比较 |
五、常见坑点
坑1:第一行的 NULL
LAG 取上一行,第一行必然返回 NULL。计算环比时需处理 NULL(通常跳过或用 COALESCE 给默认值)。
坑2:PARTITION BY 边界
LAG 不会跨分区取值。如果在 A 组最后一行执行 LAG(1),取的是 A 组倒数第二行,而不是 B 组第一行。
六、面试怎么考
- "怎么用 SQL 算环比?" → LAG + 除法
- "怎么判断用户是否连续登录?" → LAG + DATEDIFF
- "LAG 和 LEAD 的区别?" → 一个看过去,一个看未来
七、相关面试题
- 01. 股票波峰波谷 — LAG + LEAD 前后比较
- 04. 用户活跃区间合并 — LAG + 累计 MAX
- 03. 每月销售额与上月的同比环比 — LAG 环比计算
- 14. 连续3天交易金额递增的用户 — LAG 链式比较
- 更多窗口函数面试题 →
📱关注公众号
「数据仓库技术」文章同步更新,不错过每一篇干货

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