做数据分析的人迟早会遇到这样的场景:对比上月销售额、标记流失风险用户、给产品打排行榜。这些需求用传统自连接写起来又慢又乱,而LEAD、LAG、RANK这几个窗口函数,能让查询简洁一个数量级。

本文聚焦五个高频进阶函数:LEAD、LAG、RANK、DENSE_RANK、NTILE。假设你已熟悉OVER()和PARTITION BY基础语法。

打开网易新闻 查看精彩图片

LEAD与LAG:向前看,向后看

LAG取前N行数据,LEAD取后N行数据。核心场景是时间序列对比——"这个月比上个月涨了多少"。

打开网易新闻 查看精彩图片

语法结构:

LAG(列名, 偏移行数, 默认值) OVER (PARTITION BY ... ORDER BY ...)

LEAD(列名, 偏移行数, 默认值) OVER (PARTITION BY ... ORDER BY ...)

偏移量默认是1,默认值用于处理边界NULL。一个小技巧:把默认值设0,能让报表首行显示干净,省去下游处理麻烦。

月度营收环比计算示例:按产品ID分区、月份排序,用LAG(revenue, 1, 0)取出上月收入,当前值减去前值即得变动额。相比自连接方案,代码量减半,执行计划更优。

LEAD的典型场景是流失预警。取同一客户的下一单日期,若为空或间隔超90天,则标记"流失风险"。这类查询以前需要orders表自连接,条件还要写o2.order_date > o1.order_date,现在一个LEAD就解决。

打开网易新闻 查看精彩图片

RANK、DENSE_RANK、ROW_NUMBER:三种排法,三种用途

三者都给行编号,但处理并列的方式截然不同:

ROW_NUMBER() — 遇并列随机排,1、2、3、4
RANK() — 遇并列跳号,1、2、2、4
DENSE_RANK() — 遇并列不跳号,1、2、2、3

选错函数会导致报表逻辑错误。比如销售排行榜,若两人并列第二,RANK会让下一人排第四(跳过了3),DENSE_RANK则继续排第三。业务要"第几名"还是"前N个",决定了该用哪个。

NTILE:等分桶,做分层

NTILE(n)把数据切成n个桶,每桶行数大致相等。常用于用户分层——按消费额切成10档,看每档贡献占比。

五个函数覆盖了三类核心需求:跨行取值(LEAD/LAG)、竞争排名(RANK家族)、分位分层(NTILE)。掌握这组工具,大部分分析场景不再需要自连接和子查询嵌套。