LEAD()和LAG()仅返回值,不能直接判断趋势;需结合差值或比较运算(如sales > LEAD(sales,1))才能识别上升/下降方向。
直接用或做趋势方向判断本身不靠谱——它只取值,不判断趋势;真正要识别“上升/下降”,得靠差值、符号或连续模式,而不是函数名本身。
LEAD/LAG 返回的只是值,不是趋势结论
很多人以为
拿到下一行销量,就能直接说“这是增长”,其实不是。它只返回一个数字,后续必须显式做比较才能得出方向:
→ 下降(当前比下一天高)
漏掉
子句会报错,或被数据库当普通聚合处理,结果完全不可信
如果日期有空缺(比如跳过周末),
拿的是“下一条记录”,不一定是“明天”,趋势标签就失真
用 CASE + 窗口差值判断单步趋势最稳妥
单次对比(日环比、月环比)推荐统一用
计算前值再比,语义更清晰:
注意点:
必须给
加第三参数防 NULL,否则首行
全是
:
别在
里重复写两遍
,性能差且易出错;先用子查询或 CTE 提前算好
要配合除法使用(如算增长率),但单纯判方向不需要
PARTITION BY 错位会导致趋势跨组污染
想按商品看各自趋势,却得到“所有商品混在一起排”的结果?大概率是
写错了位置:
正确:
错误:
(语法非法)
更隐蔽的错:把
放在
后面,部分数据库会静默忽略分区
如果
有 NULL,所有 NULL 值会被归为同一组,导致多个商品趋势串在一起
连续多期趋势(如“连续3个月上升”)不能靠单个 LEAD/LAG 解决
单次
只能看一步,要识别单调序列,得结合行号与累计逻辑:
先用
算每期相对前一期的变化符号(+1 / -1 / 0)
再用
窗口函数对符号做累加,找连续非负段
或者用
配合自连接,比用
更可靠(避免同值跳号破坏连续性)
补全时间维度仍是前提——没数据的月份不参与计算,就会把“断层”误认为“拐点”
真正难的从来不是写对一个
,而是让时间对齐、分组干净、空值可控——这三处一错,趋势结论就全偏了。
LEAD()LAG()LEAD(sales, 1)sales > LEAD(sales, 1) OVER (ORDER BY date)sales → 上升(当前比下一天低)OVERLEAD(sales, 1)LAG()SELECT
date,
sales_amount,
LAG(sales_amount) OVER (ORDER BY date) AS prev_amount,
CASE
WHEN sales_amount > LAG(sales_amount) OVER (ORDER BY date) THEN '↑'
WHEN sales_amount < LAG(sales_amount) OVER (ORDER BY date) THEN '↓'
ELSE '→'
END AS trend
FROM daily_sales;LAG()trendNULLLAG(sales_amount, 1, 0)CASELAG()prev_amountNULLIF(prev_amount, 0)PARTITION BY product_idLAG(sales, 1) OVER (PARTITION BY product_id ORDER BY date)LAG(sales, 1) OVER (ORDER BY date) PARTITION BY product_idPARTITION BYORDER BYproduct_idLEAD()LAG()SUM()ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY date)RANK()LEAD()