命名为Windows
可以定义Windows并为其指定名称,以便在OVER
子句中引用它们。为此,请使用WINDOW
子句。如果查询中存在WINDOW
子句,则该子句位于HAVING
and ORDER BY
子句的位置之间,并具有以下语法:
WINDOW window_nameAS (window_spec) [, window_nameAS (window_spec)] ...
对于每个窗口定义,window_name
都是窗口名称,并且window_spec
是与OVER
子句括号之间给出的窗口规范类型相同的窗口规范,如“窗口函数的概念和语法”中所述:
window_spec: [window_name] [partition_clause] [order_clause] [frame_clause]
甲WINDOW
子句对于其中多个查询是有用OVER
的条款,否则定义相同的窗口。相反,您可以一次定义窗口,给它命名,然后在OVER
子句中引用该名称。考虑以下查询,它多次定义了相同的窗口:
SELECT val, ROW_NUMBER()OVER (ORDER BY val)AS 'row_number', RANK()OVER (ORDER BY val)AS 'rank', DENSE_RANK()OVER (ORDER BY val)AS 'dense_rank'FROM numbers;
通过使用WINDOW
一次定义窗口并在OVER
子句中按名称引用窗口,可以更简单地编写查询:
SELECT val, ROW_NUMBER()OVER wAS 'row_number', RANK()OVER wAS 'rank', DENSE_RANK()OVER wAS 'dense_rank'FROM numbersWINDOW wAS (ORDER BY val);
命名窗口还使您更容易尝试使用窗口定义来参见对查询结果的影响。您只需要修改WINDOW
子句中的窗口定义,而无需修改多个OVER
子句定义。
如果OVER
子句使用而不是,则可以通过添加其他子句来修改命名窗口。例如,此查询定义一个包含分区的窗口,并在子句中使用该窗口以不同方式修改该窗口:OVER(window_name...)
OVER window_name
ORDER BY
OVER
SELECT DISTINCT year, country, FIRST_VALUE(year)OVER (wORDER BY yearASC )AS first , FIRST_VALUE(year)OVER (wORDER BY yearDESC )AS last FROM salesWINDOW wAS (PARTITION BY country);
一个OVER
子句只能添加属性命名的窗口,不能修改它们。如果命名的窗口定义包含分区,排序或框架属性,则OVER
引用窗口名称的子句也不能包含相同类型的属性,否则会发生错误:
允许使用此构造,因为窗口定义和referring
OVER
子句不包含相同类型的属性:OVER (wORDER BY country) ...WINDOW wAS (PARTITION BY country)不允许使用此构造,因为该
OVER
子句指定PARTITION BY
了已经具有的命名窗口PARTITION BY
:OVER (wPARTITION BY year) ...WINDOW wAS (PARTITION BY country)
命名窗口的定义本身可以以开头window_name
。在这种情况下,允许向前和向后引用,但不允许循环:
这是允许的;它包含正向和反向引用,但没有循环:
WINDOW w1AS (w2), w2AS (), w3AS (w1)不允许这样做,因为它包含一个循环:
WINDOW w1AS (w2), w2AS (w3), w3AS (w1)