窗口函数

​ InCloud ZNBASE支持在选择查询返回的行的子集上应用函数。这种函数称为窗口函数,它允许一次对多个行进行运算来计算值。窗口函数所操作的行的子集称为窗口。

语法格式

窗口函数使用的语法格式如下:

窗口函数 - 图1

  • window_specification

窗口函数 - 图2

  • opt_partition_clause

窗口函数 - 图3

  • opt_sort_clause

窗口函数 - 图4

  • sort_clause

窗口函数 - 图5

  • opt_frame_clause

窗口函数 - 图6

  • frame_extent

窗口函数 - 图7

  • frame_bound

窗口函数 - 图8

参数说明

  • window_name

    新窗口的名称。

  • opt_existing_window_name

    现有窗口的可选名称(在另一个窗口定义中定义)。

  • opt_partition_clause

    可选PARTITION BY子句。

  • opt_sort_clause

    可选ORDER BY子句。

  • frame_bound

    可选的窗口边界。

  • 有效的起始边界包括UNBOUNDED PRECEDING,<offset> PRECEDING,和CURRENT ROW。

  • 有效结束边界包括UNBOUNDED FOLLOWING,<offset> FOLLOWING,和CURRENT ROW。

窗口函数工作原理

窗口函数的作用是:

  1. 使用选择查询创建“虚拟表”。

  2. 将该表拆分为带有窗口定义的窗口。可以在OVER子句中,直接在窗口函数之后或在WINDOW子句中定义窗口,作为选择查询的一部分。

  3. 将窗口函数应用于每个窗口。

例如:考虑一个查询,其中为每个窗口函数调用定义了窗口:

SELECT DISTINCT(city), SUM(revenue) OVER () AS total_revenue, SUM(revenue) OVER (PARTITION BY city) AS city_revenue FROM rides ORDER BY city_revenue DESC; |

其操作可以描述如下(此处列出的编号步骤与下图中的编号相对应):

  1. 外层SELECT DISTINCT(city) … FROM rides 创建一个“虚拟表”,窗口函数将在该表上运行。

  2. 窗口函数SUM(revenue) OVER ()在包含查询输出的所有行的窗口上运行。

  3. 窗口函数SUM(revenue) OVER (PARTITION BY city)依次作用于多个窗口。每个窗口都包含revenue不同城市分区(阿姆斯特丹,波士顿,洛杉矶等)的列。

窗口函数 - 图9

注意:

​ 使用窗口函数最重要的部分是了解窗口函数将在其窗口中操作的数据。默认情况下,窗口包括分区的所有行。如果将分区排序,则默认窗口将包括从分区第一行到当前行的所有行。换句话说,ORDER BY在创建窗口(例如PARTITION BY x ORDER by y)时添加子句具有以下效果:

  • 它使窗口内的行排序。

  • 它更改了调用函数的行-不再是窗口中的所有行,而是“第一”行和当前行之间的子集。

换句话说,可以在任一窗口上运行窗口函数:

  • PARTITION BY子句创建的窗口中的所有行 ,例如SELECT f(x) OVER () FROM z。

  • 如果使用SELECT f(x) OVER (PARTITION BY x ORDER BY y) FROM z创建窗口,则是窗口中的行的子集。

​ 如果没有看到期望从窗口函数获得的结果,则可能需要在窗口定义中明确指定窗口边界。如果要在同一窗口上运行单独的窗口函数,则可以在WINDOW子句中定义一次窗口,然后在调用窗口函数时通过其名称引用该窗口。

语法示例

示例1:将行号添加到查询输出。

SELECT row_number() OVER (), * FROM ( SELECT DISTINCT name, sum(revenue) OVER ( PARTITION BY name ) AS “total rider revenue” FROM users JOIN rides ON users.id = rides.rider_id ORDER BY “total rider revenue” DESC LIMIT 10 ); |

支持的窗口函数的完整列表

下面是本数据库所支持的所有的窗口函数以及其相关说明:

功能→返回说明
cume_dist() → float计算当前行的相对秩:(当前行前面或与当前行对等的行数)/(总行数)。
dense_rank() → int计算当前行的秩(不带间隙);此函数计算对等组。
first_value(val: bool) → bool返回在窗口的第一行处计算的值。
first_value(val: bytes) → bytes返回在窗口的第一行处计算的值。
first_value(val: date) → date返回在窗口的第一行处计算的值。
first_value(val: decimal) → decimal返回在窗口的第一行处计算的值。
first_value(val: float) → float返回在窗口的第一行处计算的值。
first_value(val: inet) → inet返回在窗口的第一行处计算的值。
first_value(val: int) → int返回在窗口的第一行处计算的值。
first_value(val: interval) → interval返回在窗口的第一行处计算的值。
first_value(val: string) → string返回在窗口的第一行处计算的值。
first_value(val: time) → time返回在窗口的第一行处计算的值。
first_value(val: timestamp) → timestamp返回在窗口的第一行处计算的值。
first_value(val: timestamptz) → timestamptz返回在窗口的第一行处计算的值。
first_value(val: uuid) → uuid返回在窗口的第一行处计算的值。
first_value(val: jsonb) → jsonb返回在窗口的第一行处计算的值。
first_value(val: oid) → oid返回在窗口的第一行处计算的值。
first_value(val: varbit) → varbit返回在窗口的第一行处计算的值。
lag(val: bool) → bool返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: bool, n: int) → bool返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: bool, n: int, default: bool) → bool返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: bytes) → bytes返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: bytes, n: int) → bytes返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: bytes, n: int, default: bytes) → bytes返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: date) → date返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: date, n: int) → date返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: date, n: int, default: date) → date返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: decimal) → decimal返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: decimal, n: int) → decimal返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: decimal, n: int, default: decimal) → decimal返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: float) → float返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: float, n: int) → float返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: float, n: int, default: float) → float返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: inet) → inet返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: inet, n: int) → inet返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: inet, n: int, default: inet) → inet返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: int) → int返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: int, n: int) → int返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: int, n: int, default: int) → int返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: interval) → interval返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: interval, n: int) → interval返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: interval, n: int, default: interval) → interval返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: string) → string返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: string, n: int) → string返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: string, n: int, default: string) → string返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: time) → time返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: time, n: int) → time返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: time, n: int, default: time) → time返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: timestamp) → timestamp返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: timestamp, n: int) → timestamp返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: timestamp, n: int, default: timestamp) → timestamp返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: timestamptz) → timestamptz返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: timestamptz, n: int) → timestamptz返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: timestamptz, n: int, default: timestamptz) → timestamptz返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: uuid) → uuid返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: uuid, n: int) → uuid返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: uuid, n: int, default: uuid) → uuid返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: jsonb) → jsonb返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: jsonb, n: int) → jsonb返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: jsonb, n: int, default: jsonb) → jsonb返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: oid) → oid返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: oid, n: int) → oid返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: oid, n: int, default: oid) → oid返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lag(val: varbit) → varbit返回在当前行的分区中的前一行计算的val;如果没有这样的行,则返回null。
lag(val: varbit, n: int) → varbit返回在其分区内当前行之前n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lag(val: varbit, n: int, default: varbit) → varbit返回在其分区内当前行之前n行的行上计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
last_value(val: bool) → bool返回在窗口内的最后一行计算的值。
last_value(val: bytes) → bytes返回在窗口内的最后一行计算的值。
last_value(val: date) → date返回在窗口内的最后一行计算的值。
last_value(val: decimal) → decimal返回在窗口内的最后一行计算的值。
last_value(val: float) → float返回在窗口内的最后一行计算的值。
last_value(val: inet) → inet返回在窗口内的最后一行计算的值。
last_value(val: int) → int返回在窗口内的最后一行计算的值。
last_value(val: interval) → interval返回在窗口内的最后一行计算的值。
last_value(val: string) → string返回在窗口内的最后一行计算的值。
last_value(val: time) → time返回在窗口内的最后一行计算的值。
last_value(val: timestamp) → timestamp返回在窗口内的最后一行计算的值。
last_value(val: timestamptz) → timestamptz返回在窗口内的最后一行计算的值。
last_value(val: uuid) → uuid返回在窗口内的最后一行计算的值。
last_value(val: jsonb) → jsonb返回在窗口内的最后一行计算的值。
last_value(val: oid) → oid返回在窗口内的最后一行计算的值。
last_value(val: varbit) → varbit返回在窗口内的最后一行计算的值。
lead(val: bool) → bool返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: bool, n: int) → bool返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: bool, n: int, default: bool) → bool返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: bytes) → bytes返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: bytes, n: int) → bytes返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: bytes, n: int, default: bytes) → bytes返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: date) → date返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: date, n: int) → date返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: date, n: int, default: date) → date返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: decimal) → decimal返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: decimal, n: int) → decimal返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: decimal, n: int, default: decimal) → decimal返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: float) → float返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: float, n: int) → float返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: float, n: int, default: float) → float返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: inet) → inet返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: inet, n: int) → inet返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: inet, n: int, default: inet) → inet返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: int) → int返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: int, n: int) → int返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: int, n: int, default: int) → int返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: interval) → interval返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: interval, n: int) → interval返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: interval, n: int, default: interval) → interval返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: string) → string返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: string, n: int) → string返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: string, n: int, default: string) → string返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: time) → time返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: time, n: int) → time返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: time, n: int, default: time) → time返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: timestamp) → timestamp返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: timestamp, n: int) → timestamp返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: timestamp, n: int, default: timestamp) → timestamp返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: timestamptz) → timestamptz返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: timestamptz, n: int) → timestamptz返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: timestamptz, n: int, default: timestamptz) → timestamptz返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: uuid) → uuid返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: uuid, n: int) → uuid返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: uuid, n: int, default: uuid) → uuid返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: jsonb) → jsonb返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: jsonb, n: int) → jsonb返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: jsonb, n: int, default: jsonb) → jsonb返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: oid) → oid返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: oid, n: int) → oid返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: oid, n: int, default: oid) → oid返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
lead(val: varbit) → varbit返回在当前行分区内的下一行计算的val;如果没有这样的行,则返回null。
lead(val: varbit, n: int) → varbit返回在其分区内当前行后面n行的行上计算的val;如果没有这样的行,则返回空值。n是针对当前行计算的。
lead(val: varbit, n: int, default: varbit) → varbit返回在其分区内当前行后面n行处计算的val;如果没有,则返回默认值(必须与val类型相同)。n和default都是根据当前行计算的。
nth_value(val: bool, n: int) → bool返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: bytes, n: int) → bytes返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: date, n: int) → date返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: decimal, n: int) → decimal返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: float, n: int) → float返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: inet, n: int) → inet返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: int, n: int) → int返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: interval, n: int) → interval返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: string, n: int) → string返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: time, n: int) → time返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: timestamp, n: int) → timestamp返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: timestamptz, n: int) → timestamptz返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: uuid, n: int) → uuid返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: jsonb, n: int) → jsonb返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: oid, n: int) → oid返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
nth_value(val: varbit, n: int) → varbit返回在窗口内的第n行(从1开始计算)处计算的val;如果没有这样的行,则返回null。
ntile(n: int) → int计算一个从1到n的整数,将分区尽可能等分。
percent_rank() → float计算当前行的相对秩:(秩-1)/(总行数-1)。
rank() → int计算具有间隙的当前行的秩;与第一个对等行的行数相同。
row_number() → int计算其分区内当前行的数目,从1开始计算。