lead是窗口函数,用于获取当前行之后第n行的值,基本语法为lead(column, offset, default),必须配合over(order by ...)使用,支持partition by分组计算,常用于环比分析等场景。

LEAD函数的基本用法和参数含义
LEAD 是窗口函数,用来获取当前行之后第 N 行的值。它不改变原表结构,只在查询时动态“向前看”。最简形式是 LEAD(column),默认取下 1 行;带偏移量写法是 LEAD(column, offset),比如 LEAD(sales, 2) 就是取后第 2 行的 sales 值。
第三个参数可设默认值:LEAD(sales, 1, 0) 表示下一行为空时填 0,避免结果出现 NULL 干扰后续计算。
必须配合 OVER 子句使用,且 ORDER BY 不可省略——没排序就谈不上“下一行”。常见错误是漏写或错写排序字段,导致趋势方向完全反了。
用LEAD计算环比变化(如月度增长率)
环比 = (当期值 - 上期值) / 上期值,但 LEAD 是“向后看”,所以得用它拿“下一期”,再和当前行做减法。例如分析每月销售额趋势:
SELECT
month,
sales,
LEAD(sales, 1) OVER (ORDER BY month) AS next_month_sales,
ROUND(
(LEAD(sales, 1) OVER (ORDER BY month) - sales) * 100.0 / NULLIF(sales, 0), 2
) AS mom_growth_pct
FROM sales_data;
注意几点:
-
NULLIF(sales, 0)防止除零错误,比直接写/ sales更安全 - 两次写
LEAD(...) OVER (...)不会提升性能开销,优化器通常会复用计算 - 如果数据按
year, month多级排序,ORDER BY year, month才能保证跨年连续性 - 最后一个月的
next_month_sales是NULL,对应增长率也是NULL,这是正常行为,不是 bug
LEAD配合PARTITION BY处理多维度分组趋势
实际业务中,趋势常需按产品线、地区等维度分别计算。比如每个 product_id 独立看月度增长,就得加 PARTITION BY:
SELECT
product_id,
month,
sales,
LEAD(sales) OVER (
PARTITION BY product_id
ORDER BY month
) AS next_sales
FROM sales_by_product;
关键点:
-
PARTITION BY在ORDER BY之前执行,每组内单独排序、单独编号,“下一行”只在本组内找 - 若漏写
PARTITION BY但写了ORDER BY,所有产品混在一起排,趋势就乱了 - 分区字段不能参与排序逻辑,比如
PARTITION BY region+ORDER BY month合理,但ORDER BY region, month会让不同地区数据穿插,失去分组意义
LEAD和LAG混用容易踩的坑
有人想“既看上期又看下期”,顺手写 LAG(sales) 和 LEAD(sales),结果发现两列值一样——大概率是 ORDER BY 字段有重复值,导致窗口排序不稳定。
例如按 date 排序,但多条记录 date 相同,数据库无法确定谁先谁后,LAG 和 LEAD 可能随机抓取同行或跳行。
解决方法:
- 在
ORDER BY中加入唯一字段兜底,如ORDER BY date, id - 避免对无序字段(如未索引的文本列)直接排序用于窗口函数
-
LEAD的offset超出当前分区行数时,一律返回NULL(或你指定的默认值),不会报错,但可能掩盖数据断层问题
跨行计算真正难的不是语法,而是确认“哪一行才算下一行”——时间字段是否严格递增、是否存在空缺、分区边界是否清晰,这些比函数本身更影响结果可信度。










