# 12.21.4 命名窗口
可以定义 Windows 并为其命名以在其中引用它们超过
条款。为此,请使用窗户
条款。如果出现在查询中,则窗户
子句介于拥有
和订购方式
子句,并具有以下语法:
WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...
对于每个窗口定义,*窗口名称
是窗口名称,并且窗口规格
*与括号中给出的窗口规范类型相同超过
条款,如中所述第 12.21.2 节,“窗口函数概念和语法”:
window_spec:
[window_name] [partition_clause] [order_clause] [frame_clause]
一种窗户
子句对于多个查询很有用超过
否则,子句将定义相同的窗口。相反,您可以定义一次窗口,给它一个名称,然后在超过
条款。考虑这个查询,它多次定义同一个窗口:
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;
查询可以通过使用更简单地编写窗户
定义一次窗口并在超过
条款:
SELECT
val,
ROW_NUMBER() OVER w AS 'row_number',
RANK() OVER w AS 'rank',
DENSE_RANK() OVER w AS 'dense_rank'
FROM numbers
WINDOW w AS (ORDER BY val);
命名窗口还可以更轻松地试验窗口定义以查看对查询结果的影响。您只需要修改窗口定义窗户
子句,而不是多个超过
条款定义。
如果超过
子句使用超过 (*
窗口名称* ...)
而不是超过 *
窗口名称*
,命名窗口可以通过添加其他子句来修改。例如,此查询定义了一个包含分区的窗口,并使用订购方式
在里面超过
以不同方式修改窗口的子句:
SELECT
DISTINCT year, country,
FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first,
FIRST_VALUE(year) OVER (w ORDER BY year DESC) AS last
FROM sales
WINDOW w AS (PARTITION BY country);
一个超过
子句只能将属性添加到命名窗口,不能修改它们。如果命名窗口定义包含分区、排序或框架属性,则超过
引用窗口名称的子句不能同时包含相同类型的属性,否则会发生错误:
此构造是允许的,因为窗口定义和引用
超过
子句不包含相同类型的属性:OVER (w ORDER BY country) ... WINDOW w AS (PARTITION BY country)
这种构造是不允许的,因为
超过
条款规定分区方式
对于已经有的命名窗口分区方式
:OVER (w PARTITION BY year) ... WINDOW w AS (PARTITION BY country)
命名窗口的定义本身可以以*
窗口名称
*.在这种情况下,允许向前和向后引用,但不允许循环:这是允许的;它包含前向和后向引用,但没有循环:
WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)
这是不允许的,因为它包含一个循环:
WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1)