首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >spark 窗口函数速查表

spark 窗口函数速查表

作者头像
数据仓库晨曦
发布2026-06-23 17:28:35
发布2026-06-23 17:28:35
730
举报
文章被收录于专栏:数据仓库技术数据仓库技术

语法结构

代码语言:javascript
复制
函数() OVER(
    PARTITION BY col       -- 分区(可选)
    ORDER BY col           -- 排序(部分函数必需)
    ROWS|RANGE BETWEEN ... -- 帧(仅聚合/首尾类有效)
)

函数分类总览

类别

函数

帧有效

需要 ORDER BY

排名

ROW_NUMBER, RANK, DENSE_RANK

偏移

LAG, LEAD

聚合

SUM, AVG, COUNT, MAX, MIN

通常需要

首尾定位

FIRST_VALUE, LAST_VALUE, NTH_VALUE

分布

NTILE, PERCENT_RANK, CUME_DIST

一、排名类

函数

行为

重复值处理

典型场景

ROW_NUMBER()

连续编号 1,2,3,4,5

不并列,不跳号

去重取最新、分组 Top-N

RANK()

并列跳号 1,1,3,3,5

并列同号,后续跳号

排名允许并列

DENSE_RANK()

并列不跳号 1,1,2,2,3

并列同号,后续不跳

连续等级划分

代码语言:javascript
复制
-- 每部门薪资 Top 3(允许并列)
SELECT * FROM (
    SELECT *, DENSE_RANK() OVER(PARTITION BY dept ORDER BY salary DESC) as rk
    FROM employee
) t WHERE rk <= 3;

二、偏移类

函数

语法

说明

LAG(col, n, default)

取前第 n 行

默认 n=1,default=NULL

LEAD(col, n, default)

取后第 n 行

默认 n=1,default=NULL

代码语言:javascript
复制
-- 环比计算
SELECT
    month, amount,
    amount - LAG(amount, 1) OVER(ORDER BY month) as mom_change
FROM sales;

-- 计算相邻事件间隔
SELECT
    user_id, event_time,
    DATEDIFF(event_time, LAG(event_time) OVER(PARTITION BY user_id ORDER BY event_time)) as gap_days
FROM user_log;

三、聚合类

函数

说明

常见帧搭配

SUM()

求和

累计求和、滑动求和

AVG()

平均

移动平均

COUNT()

计数

滑动窗口内行数

MAX() / MIN()

极值

滑动最大/最小值

代码语言:javascript
复制
-- 累计求和(默认帧)
SUM(amount) OVER(PARTITION BY user_id ORDER BY month)

-- 近3行移动平均
AVG(amount) OVER(PARTITION BY user_id ORDER BY month
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW)

-- 全分区求和(不加 ORDER BY 则帧为整个分区)
SUM(amount) OVER(PARTITION BY dept)

四、首尾定位类

函数

说明

注意事项

FIRST_VALUE(col)

帧内第一行的值

LAST_VALUE(col)

帧内最后一行的值

⚠️ 默认帧陷阱

NTH_VALUE(col, n)

帧内第 n 行的值

n 从 1 开始

代码语言:javascript
复制
-- LAST_VALUE 陷阱:默认帧是 UNBOUNDED PRECEDING TO CURRENT ROW
-- 必须显式指定帧才能拿到分区最后一行
LAST_VALUE(amount) OVER(PARTITION BY name ORDER BY month
    ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)

五、分布类

函数

公式

结果范围

说明

NTILE(n)

1 ~ n

等分为 n 桶

PERCENT_RANK()

(rank - 1) / (rows - 1)

0 ~ 1

百分比排名

CUME_DIST()

count(≤当前值) / rows

0 ~ 1

累积分布比例

代码语言:javascript
复制
-- 按销售额分4档
NTILE(4) OVER(ORDER BY amount DESC) as quartile

-- 百分位排名
PERCENT_RANK() OVER(PARTITION BY dept ORDER BY salary) as pct

帧(Frame)速查

帧的有效范围

帧定义并非对所有窗口函数生效。只有计算结果依赖"看哪些行"的函数才受帧影响:

类别

帧有效

原因

聚合类(SUM/AVG/COUNT/MAX/MIN)

帧决定对哪些行做聚合运算

首尾定位类(FIRST_VALUE/LAST_VALUE/NTH_VALUE)

帧决定在哪个范围内取第几行

排名类(ROW_NUMBER/RANK/DENSE_RANK)

排名基于整个分区的相对位置,不存在"部分排名"

偏移类(LAG/LEAD)

语义固定为"前/后第n行",与帧范围无关

分布类(NTILE/PERCENT_RANK/CUME_DIST)

分布计算需要完整分区数据

实际行为:对帧无效的函数,即使写了 ROWS BETWEEN ...,数据库会直接忽略,不会报错,但也不会生效。

语法

代码语言:javascript
复制
{ROWS | RANGE} BETWEEN <起点> AND <终点>

边界关键词

代码语言:javascript
复制
分区第一行

常用帧模式

模式

写法

用途

累计

ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

累计求和(默认)

滑动窗口

ROWS BETWEEN 2 PRECEDING AND CURRENT ROW

近3行移动平均

居中窗口

ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING

平滑处理

整个分区

ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING

分区总计

ROWS vs RANGE

ROWS

RANGE

计算方式

按物理行数

按排序列的值

重复值

每行独立计算

相同值的行视为同一位置

性能

更快

略慢

默认

有 ORDER BY 时的默认帧类型

代码语言:javascript
复制
-- 示例:ORDER BY amount,数据为 900, 900, 1100
-- ROWS: 第1行累计=900, 第2行累计=1800
-- RANGE: 第1行累计=1800, 第2行累计=1800(两个900一起纳入)

默认帧规则

代码语言:javascript
复制
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW

⚠️ 这是 LAST_VALUE 陷阱的根源:有 ORDER BY 时默认帧只到当前行,所以 LAST_VALUE 返回的是当前行自己。


高频面试/实战模式

代码语言:javascript
复制
ROW_NUMBER() OVER(PARTITION BY ... ORDER BY ... DESC)
 + WHERE rk <= N
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-06-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 语法结构
  • 函数分类总览
  • 一、排名类
  • 二、偏移类
  • 三、聚合类
  • 四、首尾定位类
  • 五、分布类
  • 帧(Frame)速查
    • 帧的有效范围
    • 语法
    • 边界关键词
    • 常用帧模式
    • ROWS vs RANGE
  • 默认帧规则
  • 高频面试/实战模式
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档