窗口函数语法摘要
标准窗口函数语法如下所示。
function (expression) OVER ( [ PARTITION BY expr_list ] [ ORDER BY order_list [ frame_clause ] ] )
其中,function 是本部分介绍的函数之一。
expr_list 如下所示。
expression | column_name [, expr_list ]
order_list 如下所示。
expression | column_name [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ] [, order_list ]
frame_clause 如下所示。
ROWS { UNBOUNDED PRECEDING | unsigned_value PRECEDING | CURRENT ROW } | { BETWEEN { UNBOUNDED PRECEDING | unsigned_value { PRECEDING | FOLLOWING } | CURRENT ROW} AND { UNBOUNDED FOLLOWING | unsigned_value { PRECEDING | FOLLOWING } | CURRENT ROW }}
Arguments
- 函数
-
窗口函数。有关详细信息,请参阅各个函数描述。
- OVER
-
定义窗口规范的子句。OVER 子句是窗口函数必需的,并可区分窗口函数与其他 SQL 函数。
- PARTITION BY expr_list
-
(可选)PARTITION BY 子句将结果集细分为分区,与 GROUP BY 子句很类似。如果存在分区子句,则为每个分区中的行计算该函数。如果未指定任何分区子句,则一个分区包含整个表,并为整个表计算该函数。
排名函数 DENSE_RANK、NTILE、RANK 和 ROW_NUMBER 需要全局比较结果集中的所有行。使用 PARTITION BY 子句时,查询优化程序可通过根据分区跨多个切片分布工作负载来并行运行每个聚合。如果不存在 PARTITION BY 子句,则必须在一个切片上按顺序运行聚合步骤,这可能对性能产生显著的负面影响,特别是对于大型集群。
Amazon Redshift 不支持 PARTITION BY 子句中的字符串文本。
- ORDER BY order_list
-
(可选)窗口函数将应用于每个分区中根据 ORDER BY 中的顺序规范排序的行。此 ORDER BY 子句与 frame_clause 中的 ORDER BY 子句不同且完全不相关。ORDER BY 子句可在没有 PARTITION BY 子句的情况下使用。
对于排名函数,ORDER BY 子句确定排名值的度量。对于聚合函数,分区的行必须在为每个框架计算聚合函数之前进行排序。有关窗口函数的更多信息,请参阅 窗口函数。
顺序列表中需要列标识符或计算结果为列标识符的表达式。常数和常数表达式都不可用作列名称的替代。
NULLS 值将被视为其自己的组,并根据 NULLS FIRST 或 NULLS LAST 选项进行排序和排名。默认情况下,按 ASC 顺序最后对 NULL 值进行排序和排名,按 DESC 顺序首先对 NULL 值进行排序和排名。
Amazon Redshift 不支持 ORDER BY 子句中的字符串文本。
如果省略 ORDER BY 子句,则行的顺序是不确定的。
注意
在任何并行系统(如 Amazon Redshift)中,如果 ORDER BY 子句未生成数据的唯一排序和总排序,则行的顺序是不确定的。也就是说,如果 ORDER BY 表达式生成重复的值(部分排序),则这些行的返回顺序可能会因 Amazon Redshift 的运行而异。反过来,窗口函数可能返回意外的或不一致的结果。有关更多信息,请参阅窗口函数的唯一数据排序。
- column_name
-
执行分区或排序操作所依据的列的名称。
- ASC | DESC
-
一个定义表达式的排序顺序的选项,如下所示:
-
ASC:升序(例如,按数值的从低到高的顺序和字符串的从 A 到 Z 的顺序)。如果未指定选项,则默认情况下将按升序对数据进行排序。
-
DESC:降序(按数值的从高到低的顺序和字符串的从 Z 到 A 的顺序)。
-
- NULLS FIRST | NULLS LAST
-
指定是应首先对 NULL 值进行排序(非 null 值之前)还是最后对 NULL 值进行排序(非 null 值之后)的选项。默认情况下,按 ASC 顺序最后对 NULLS 进行排序和排名,按 DESC 顺序首先对 NULLS 进行排序和排名。
- frame_clause
-
对于聚合函数,框架子句在使用 ORDER BY 时进一步优化函数窗口中的行集。它使您可以包含或排除已排序结果中的行集。框架子句包括 ROWS 关键字和关联的说明符。
frame 子句不适用于排名函数。同时,在聚合函数的 OVER 子句中未使用 ORDER BY 子句时不需要框架子句。如果 ORDER BY 子句用于聚合函数,则需要显式框架子句。
未指定 ORDER BY 子句时,隐式框架是无界的:等同于 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING。
- ROWS
-
此子句通过从当前行中指定物理偏移来定义窗口框架。
此子句指定当前行中的值将并入的当前窗口或分区中的行。它使用指定行位置的参数,行位置可位于当前行之前或之后。所有窗口框架的参考点为当前行。当窗口框架向前滑向分区中时,每个行会依次成为当前行。
框架可以是一组超过并包括当前行的行。
{UNBOUNDED PRECEDING | offset PRECEDING | CURRENT ROW}或者可以是两个边界之间的一组行。
BETWEEN { UNBOUNDED PRECEDING | offset { PRECEDING | FOLLOWING } | CURRENT ROW } AND { UNBOUNDED FOLLOWING | offset { PRECEDING | FOLLOWING } | CURRENT ROW }UNBOUNDED PRECEDING 指示窗口从分区的第一行开始;offset PRECEDING 指示窗口开始于等同于当前行之前的偏移值的行数。UNBOUNDED PRECEDING 是默认值。
CURRENT ROW 指示窗口在当前行开始或结束。
UNBOUNDED FOLLOWING 指示窗口在分区的最后一行结束;offset FOLLOWING 指示窗口结束于等同于当前行之后的偏移值的行数。
offset 标识当前行之前或之后的实际行数。在这种情况下,offset 必须为计算结果为正数值的常数。例如,5 FOLLOWING 将在当前行之后的第 5 行结束框架。
其中,未指定 BETWEEN,框架受当前行隐式限制。例如,
ROWS 5 PRECEDING等于ROWS BETWEEN 5 PRECEDING AND CURRENT ROW。同时,ROWS UNBOUNDED FOLLOWING等于ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING。注意
您无法指定起始边界大于结束边界的框架。例如,您无法指定以下任一框架。
between 5 following and 5 preceding between current row and 2 preceding between 3 following and current row
示例
以下示例使用 WINSALES 表,如 窗口函数示例的示例表中所述。该示例解释了示例 SUM 函数的语法。
select salesid, dateid, sellerid, qty, sum(qty) over (partition by sellerid order by dateid, salesid rows unbounded preceding) as sum from winsales order by 2,1; salesid | dateid | sellerid | qty | sum ---------+------------+----------+-----+----- 30001 | 2003-08-02 | 3 | 10 | 10 10001 | 2003-12-24 | 1 | 10 | 10 10005 | 2003-12-24 | 1 | 30 | 40 40001 | 2004-01-09 | 4 | 40 | 40 10006 | 2004-01-18 | 1 | 10 | 50 20001 | 2004-02-12 | 2 | 20 | 20 40005 | 2004-02-12 | 4 | 10 | 50 20002 | 2004-02-16 | 2 | 20 | 40 30003 | 2004-04-18 | 3 | 15 | 25 30004 | 2004-04-18 | 3 | 20 | 45 30007 | 2004-09-07 | 3 | 30 | 75 (11 rows)
sum(qty) 是函数,sum 是函数,qty 是表达式。
partition by sellerid order by dateid asc, salesid asc 是 order_list。使用 partition by sellerid,该函数按卖家 ID 对结果集进行分区,这意味着每行的 sum 值仅计算该行卖家的销售量总和。order by dateid asc, salesid asc 按日期对结果进行排序,如果日期相同,则按销售 ID 排序。例如,sellerid 为 1 的行仅用于对 1 实现的销售量求和,销售按第一笔销售到最后一笔销售进行排序。除 1 之外的 sellerid 值实现的所有销售量都位于结果集的各自分区中,不计入 1 的销售量总和。
rows unbounded preceding 是 frame_clause。rows preceding 将 sum 函数的框架定义为包括给定行之前的所有行,unbounding 意味着对该框架向前回溯多少没有限制。回到 sellerid 1,rows unbounded preceding 表示 sum(qty) 对 1 在每一行中所实现的所有之前的销售量求和。
有关特定函数的更多示例,请参阅相应部分中的示例。