做数据分析的人迟早会遇到这样的场景:对比上月销售额、标记流失风险用户、给产品打排行榜。这些需求用传统自连接写起来又慢又乱,而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)。掌握这组工具,大部分分析场景不再需要自连接和子查询嵌套。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.