12.21.4 Named Windows命名窗口

Windows can be defined and given names by which to refer to them in OVER clauses. 窗口可以被定义和命名,在OVER子句中引用它们。To do this, use a WINDOW clause. 为此,请使用WINDOW子句。If present in a query, the WINDOW clause falls between the positions of the HAVING and ORDER BY clauses, and has this syntax:如果查询中存在WINDOW子句,则它位于HAVING子句和ORDER BY子句之间,并且具有以下语法:

WINDOW window_name AS (window_spec)
    [, window_name AS (window_spec)] ...

For each window definition, window_name is the window name, and window_spec is the same type of window specification as given between the parentheses of an OVER clause, as described in Section 12.21.2, “Window Function Concepts and Syntax”:对于每个窗口定义,window_name是窗口名称,window_specOVER子句括号之间给出的同一类型的窗口规范,如第12.21.2节,“窗口函数概念和语法”所述:

window_spec:
    [window_name] [partition_clause] [order_clause] [frame_clause]

A WINDOW clause is useful for queries in which multiple OVER clauses would otherwise define the same window. WINDOW子句对于多个OVER子句将定义同一个窗口的查询非常有用。Instead, you can define the window once, give it a name, and refer to the name in the OVER clauses. 相反,您可以定义一次窗口,给它一个名称,并在OVER子句中引用该名称。Consider this query, which defines the same window multiple times:考虑这个查询,它多次定义同一个窗口:

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;

The query can be written more simply by using WINDOW to define the window once and referring to the window by name in the OVER clauses:通过使用WINDOW定义一次窗口,并在OVER子句中按名称引用窗口,可以更简单地编写查询:

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);

A named window also makes it easier to experiment with the window definition to see the effect on query results. 命名窗口还可以更容易地试验窗口定义,以查看对查询结果的影响。You need only modify the window definition in the WINDOW clause, rather than multiple OVER clause definitions.只需修改window子句中的窗口定义,而不需要修改多个OVER子句定义。

If an OVER clause uses OVER (window_name ...) rather than OVER window_name, the named window can be modified by the addition of other clauses. 如果OVER子句使用OVER (window_name ...)而不是OVER window_name,则可以通过添加其他子句来修改指定的窗口。For example, this query defines a window that includes partitioning, and uses ORDER BY in the OVER clauses to modify the window in different ways:例如,此查询定义了一个包含分区的窗口,并使用OVER子句中的ORDER BY以不同的方式修改该窗口:

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);

An OVER clause can only add properties to a named window, not modify them. OVER子句只能向命名窗口添加属性,不能修改属性。If the named window definition includes a partitioning, ordering, or framing property, the OVER clause that refers to the window name cannot also include the same kind of property or an error occurs:如果命名窗口定义包含分区、排序或框架属性,则引用该窗口名称的OVER子句不能同时包含相同类型的属性,否则会发生错误:

The definition of a named window can itself begin with a window_name. 命名窗口的定义本身可以以window_name开始。In such cases, forward and backward references are permitted, but not cycles:在这种情况下,允许向前和向后引用,但不允许循环: