窗口函数

4 阅读3分钟

1、概念理解

1.1 定义

窗口函数是应用于查询结果中一组行(称为“窗口”)的函数,允许用户在结果集中进行计算,并且能够保留每一行的原始数据。

核心特点

  • 不聚合结果集,保留行级数据
  • 定义窗口,通过 OVER() 子句

常见的窗口函数

  • 排名类ROW_NUMBER(), RANK(), DENSE_RANK()

  • 分布类PERCENT_RANK(), CUME_DIST(), NTILE()

  • 前后值类LAG(), LEAD()

  • 头尾值类FIRST_VALUE(), LAST_VALUE()

  • 聚合函数​ 也可用作窗口函数:SUM(), AVG(), COUNT(), MAX(), MIN()

1.2 与聚合函数的区别

定义:聚合函数是用于计算一组值并返回单个值的函数,通常与 GROUP BY 子句一起使用,将数据分组并计算每组的汇总结果。

特性窗口函数聚合函数
结果集保留每一行的原始数据返回分组后的单个汇总值
使用方式使用 OVER 子句通常与 GROUP BY 一起使用
计算范围可以在整个数据集中或分区内计算在分组后的每个组内计算
示例RANK() OVER (PARTITION BY department)AVG(salary) GROUP BY department
对 NULL 的处理可自定义处理(如可选择包括或排除 NULL)通常忽略 NULL 值

1.3 OVER() 子句

OVER() 子句定义了窗口函数的“工作窗口”

PARTITION BY (分区):

  • 作用:将整个结果集划分为更小的、独立的窗口分区。窗口函数会分别应用于每个分区内部,并在跨分区边界时重置计算。

  • 类比:相当于聚合函数中的 GROUP BY,但不对结果进行聚合。

ORDER BY (排序)

  • 作用在分区内部,定义行的逻辑顺序。

  • 关键:对于许多窗口函数来说,ORDER BY隐式地定义窗口框架的范围

PARTITION BY和 ORDER BY可以单独或组合使用

1.4 窗口范围:ROWS ... AND ...

OVER()子句中使用了 ORDER BY时,默认的窗口范围是:从分区的第一行到当前行

可以通过 ROWS/RANGE BETWEEN 子句来 显式、精确地控制窗口的起始和结束边界

关键词

  • UNBOUNDED PRECEDING:分区的第一行
  • UNBOUNDED FOLLOWING:分区的最后一行
  • CURRENT ROW当前行
  • N PRECEDING:当前行之前的第N行
  • N FOLLOWING:当前行之后的第N行

ROWS VS RANGE

ROWS:基于物理行的偏移

  • 明确指定窗口的行数。
  • 表示窗口中的行数是相对于当前行的位置来确定的。
  • 适用于确切的行数计算,不考虑行的值。

RANGE:基于ORDER BY列值的逻辑偏移

  • 根据排序列的值来定义窗口,而不是具体的行数。
  • 它表示窗口可以包括所有具有相同值的行。例如,RANGE BETWEEN 100 PRECEDING AND CURRENT ROW 表示当前行及其之前所有值不超过当前值 100 的行。
  • RANGE 更加灵活,适用于需要考虑值范围的情况,但可能在处理相同值的行时导致窗口大小不固定。