窗口函数OVER(PARTITION BY)详细用法——语法+函数+开窗范围ROWS和RANGE
讲解窗口函数 OVER(PARTITION BY) 的语法结构、常见函数、ORDER BY、ROWS 与 RANGE 开窗范围差异、累计计算、排名分析场景和常见边界问题。
窗口函数可以在保留明细行的同时,计算排名、累计值、移动平均、前后行比较等结果。理解窗口函数 OVER(PARTITION BY) 详细用法,关键是掌握函数、分区、排序和开窗范围四个部分。
基本语法
窗口函数常见结构如下:
函数名(参数) OVER (
PARTITION BY 分区字段
ORDER BY 排序字段
ROWS BETWEEN ... AND ...
)partition by 决定在哪个范围内独立计算,order by 决定窗口内顺序,rows 或 range 决定当前行参与计算的窗口边界。
常见函数类型
聚合函数可以作为窗口函数使用,例如 sum、avg、count、max、min。排序函数包括 row_number、rank、dense_rank、ntile。前后行函数包括 lag、lead,常用于环比、相邻记录比较。
SELECT user_id,
order_date,
amount,
SUM(amount) OVER (
PARTITION BY user_id
ORDER BY order_date
) AS running_amount
FROM orders;这条 SQL 可以计算每个用户按订单日期累计的金额。
PARTITION BY 与 GROUP BY 的区别
group by 会把多行聚合成一行,而窗口函数不会减少明细行。也就是说,窗口函数更适合在明细数据上附加排名、累计、分组统计结果。
例如要同时展示每笔订单金额和用户总金额,用窗口函数比先聚合再 join 更直观。
ROWS 和 RANGE 的差异
ROWS 按物理行数定义窗口边界,例如当前行及前 2 行。RANGE 按排序字段的取值范围定义窗口,遇到相同排序值时,可能把多个同值行一起纳入窗口。
SUM(amount) OVER (
ORDER BY order_date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
)这表示按排序后的当前行及前 6 行计算累计。若使用 RANGE,含义会与排序字段类型和数据库实现有关,日期、数值和重复值场景下都要谨慎验证。
常见注意事项
第一,窗口函数的 order by 要尽量稳定,必要时加入唯一字段避免同值行顺序不确定。第二,不同数据库对窗口范围默认值支持不同,复杂 SQL 应显式写出边界。第三,大范围窗口可能带来排序和内存开销,需要关注执行计划。
窗口函数 OVER(PARTITION BY) 的优势在于表达能力强,但也容易因为边界理解不清产生错误结果。写窗口 SQL 时,先用少量样例数据手工推演,再扩展到生产数据,是非常有效的验证方式。


