跳到主要内容

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 的区别?" → 一个看过去,一个看未来

七、相关面试题

📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

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

交流微信二维码

你可能还想看