LEAD函数仅取下一行值,不预测;须按时间严格排序且补全缺失月份,配合LAG可做多期对比,但真实预测需结合统计模型或ML工具。

LEAD函数本身不预测,只取下一行数据
很多人以为 LEAD() 能做时间序列预测,其实它只是窗口函数里的“向下看一眼”工具——它不建模、不拟合、不 extrapolate,只把同一排序分组中下一条记录的某个字段值拉上来。所谓“预测下月销售额”,实际是用本月数据对比已知的下月真实值(比如做环比验证),或为后续预测模型准备特征(如构造 sales_t, sales_t+1 这样的配对样本)。
关键前提:数据必须按时间严格排序,且月份连续(否则 LEAD(sales, 1) 拉到的可能不是“下月”,而是“下一条记录对应的任意月份”)。
- 务必用
ORDER BY month(或ORDER BY sale_date),不能只靠插入顺序 - 如果原始数据缺某月(例如 2024-02 缺失),
LEAD()会跳到 2024-03,导致逻辑错位;此时需先补全月份(用GENERATE_SERIES或日期维表 LEFT JOIN) -
LEAD(sales, 1)默认返回NULL(当无下一行时),可加第三个参数指定默认值,如LEAD(sales, 1, 0)
正确写法:按月份排序 + 处理非连续日期
假设表 monthly_sales 有字段 sale_month(DATE 类型,每月1号)和 amount:
SELECT
sale_month,
amount AS current_month_sales,
LEAD(amount, 1) OVER (ORDER BY sale_month) AS next_month_sales,
ROUND(
(LEAD(amount, 1) OVER (ORDER BY sale_month) - amount) / NULLIF(amount, 0), 4
) AS mom_growth_rate
FROM monthly_sales
ORDER BY sale_month;
注意点:
-
NULLIF(amount, 0)防止除零错误,比CASE WHEN amount = 0 THEN NULL ELSE ... END更简洁 - 结果中最后一行的
next_month_sales一定是NULL——这是正常行为,不是 bug - 若
sale_month是字符串(如 '2024-01'),必须转成日期排序:ORDER BY TO_DATE(sale_month, 'YYYY-MM'),否则 '2024-10' 会排在 '2024-2' 前面
和 LAG 混用做多期对比很常见
单用 LEAD() 只能看下一期,但业务常需对比上月、下月、去年同期。这时组合使用更自然:
SELECT sale_month, amount, LAG(amount, 1) OVER (ORDER BY sale_month) AS prev_month, LEAD(amount, 1) OVER (ORDER BY sale_month) AS next_month, LAG(amount, 12) OVER (ORDER BY sale_month) AS same_month_last_year FROM monthly_sales;
要点:
- 所有
OVER子句必须完全一致(尤其ORDER BY),否则各列对齐错乱 - 跨年对比(如
LAG(amount, 12))依赖数据恰好按月连续且无缺失;缺一个月,去年同月就偏了 - PostgreSQL 支持
INTERVAL偏移(如LEAD(amount) OVER (ORDER BY sale_date RANGE BETWEEN '1 month' FOLLOWING AND '1 month' FOLLOWING)),但多数数据库不支持,兼容性差,不建议用于生产
真正做预测得接其他工具
如果目标确实是“预测尚未发生的下月销售额”,LEAD() 到此为止——它只能帮你组织好历史同期数据,供下一步使用:
- 导出带
amount,prev_month,prev_2month的宽表,扔给 Python 的statsmodels或prophet训练 - 在支持 ML 的数据库里(如 BigQuery ML),用
ML.ARIMA直接拟合amount时间序列,LEAD()在这里只用于生成训练标签 - 切记:把
LEAD(amount, 1)当成标签列(y),把前 N 个月 amount 当成特征列(X),才是预测建模的起点
最易被忽略的一点:时间窗口的划分必须和业务口径对齐。例如财务月从每月 25 日到次月 24 日,就不能简单用 sale_month::DATE 排序,得先转换周期再开窗。










