Skip to main content

窗口函数 OVER 子句(Window Function)

窗口函数(Window Function/Windowing Function)在与当前行相关的一组行上执行计算(类似一个“窗口”框出一定范围的行)。

"窗口"是通过 OVER 子句定义的,通常包括三个部分:

  • 窗口分区(PARTITION BY 子句):指定如何将行分成更小的集合。
  • 窗口排序(ORDER BY 子句):指定行的排序方式。此部分对于排名函数是必需的。
  • 窗口范围(ROWS 子句):指定对哪一行或行的范围进行计算。

如果您的目标是在窗口关闭时仅生成仅追加输出的计算结果,可以利用窗口关闭时触发(emit-on-window-close)策略。这种方法有助于避免不必要的计算。有关该策略的更多信息,请参阅 窗口关闭时触发

句法

window_function ( [expression [, expression ... ]] ) OVER 
( PARTITION BY partition_expression
[ ORDER BY sort_expression [ ASC | DESC ] [ NULLS { FIRST | LAST } ] [, ...] ]
[frame_clause])
note

目前,PARTITION BY 子句是必需的。如果您不想将行分成更小的集合,可以通过指定 PARTITION BY 1::int 来解决。

对于 row_numberrank 等排名窗口函数,ORDER BY 子句是必需的。

在流查询的 emit-on-window-close 模式下操作时,每个窗口函数都需要 ORDER BY 子句。请确保只指定一个列进行排序。这列通常是时间戳列,必须为其定义水位线。注意,当在另一个流查询中使用此流查询的时间戳列时,与该列关联的水位线信息不会保留。

window_function 可以是以下之一:

frame_clause 的句法是:

{ ROWS } frame_start [ frame_exclusion ]
{ ROWS } BETWEEN frame_start AND frame_end [ frame_exclusion ]

frame_startframe_end 可以是:

UNBOUNDED PRECEDING
offset PRECEDING
CURRENT ROW
offset FOLLOWING
UNBOUNDED FOLLOWING

其中 offset 是正整数。如果只指定了 frame_start,则 CURRENT ROW 将用作窗口的结束。

frame_exclusion 可以是以下之一:

EXCLUDE CURRENT ROW
EXCLUDE NO OTHERS
note

在 RisingWave 中,frame_clause 是可选的。根据是否存在 ORDER BY 子句,其默认值不同。当存在 ORDER BY 子句时,默认值是 ROWS UNBOUNDED PRECEDING AND CURRENT ROW。当不存在 ORDER BY 子句时,默认值是 ROWS UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。这与 PostgreSQL 中的行为不同。这种差异是暂时的。一旦 RisingWave 支持 RANGE frame 子句,缺省值将与 PostgreSQL 保持一致。

通用窗口函数

row_number()

row_number() 函数为结果集的分区内的每一行分配一个唯一的连续整数。编号从每个分区的第一行开始为 1,并且对于每个后续行递增 1。

row_number() 可用于将非唯一行转换为唯一行。这可以用于消除重复行。

row_number() 的句法是:

row_number()integer
note

我们建议仅在 top-N 模式查询中使用 row_number()。有关此模式的详细信息,请参见 分组 Top-N

rank()

rank() 返回当前行的排名,有间隔;即,它的同伴组中第一行的 row_number

rank() 的句法是:

rank()integer

dense_rank()

dense_rank() 返回当前行的排名,无间隔;即,如果一些行共享相同的排名,则紧接它们的行被分配下一个连续的排名。

dense_rank() 的句法是:

dense_rank()integer

lag()lead()

lag() 允许您访问结果集中前一行的值。您可以指定向后查看的行数。

lag() 的句法是:

lag ( value anycompatible [, offset const integer] )anycompatible

lead() 类似于 lag(),但它允许您访问结果集中后续行的值。

lead() 的句法是:

lead ( value anycompatible [, offset const integer] )anycompatible

first_value()last_value()

first_value() 函数返回当前窗口框架中第一行的值。

first_value() 的句法是:

first_value ( value anyelement )anyelement

last_value() 返回当前窗口框架中最后一行的值。

last_value() 的句法是:

last_value ( value anyelement )anyelement

聚合窗口函数

聚合窗口函数包括 sum()min()max()avg()count() 等。有关聚合函数的完整列表及其用法,请参见聚合函数