可以在 OVER 子句中定义窗口并为其命名。为此,请使用 WINDOW 子句。如果查询中存在 WINDOW 子句,它位于 HAVING 和 ORDER BY 子句之间,其语法如下:Windows can be defined and given names by which to refer to them
in OVER clauses. To do this, use a
WINDOW clause. If present in a query, the
WINDOW clause falls between the positions of
the HAVING and ORDER BY
clauses, and has this syntax:
WINDOWwindow_nameAS (window_spec) [,window_nameAS (window_spec)] ...
对于每个窗口定义,window_name 是窗口名称,window_spec 是与 OVER 子句括号中给出的窗口规范相同的类型,如 第 14.20.2 节,“窗口函数的概念和语法” 中所述: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 14.20.2, “Window Function Concepts and Syntax”:
window_spec: [window_name] [partition_clause] [order_clause] [frame_clause]
WINDOW 子句对于那些多个 OVER 子句本来会定义相同窗口的查询非常有用。相反,你可以只定义一次窗口,为其命名,然后在 OVER 子句中引用该名称。考虑这个查询,它多次定义了相同的窗口:A WINDOW clause is useful for queries in
which multiple OVER clauses would otherwise
define the same window. Instead, you can define the window once,
give it a name, and refer to the name in the
OVER clauses. 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;
通过使用 WINDOW 定义窗口一次,并在 OVER 子句中按名称引用窗口,可以更简单地编写查询: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:
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);
命名窗口还可以更方便地对窗口定义进行实验,以查看对查询结果的影响。你只需修改 WINDOW 子句中的窗口定义,而不是多次修改 OVER 子句定义。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.
如果 OVER 子句使用 OVER
(window_name ...) 而不是 OVER
window_name,则可以通过添加其他子句来修改命名窗口。例如,此查询定义了一个包含分区的窗口,并在 OVER 子句中使用 ORDER BY 以不同方式修改窗口:If an OVER clause uses OVER
( rather
than window_name ...)OVER
, the named
window can be modified by the addition of other clauses. For
example, this query defines a window that includes partitioning,
and uses window_nameORDER BY in the
OVER clauses to modify the window in
different ways:
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 子句只能向命名窗口添加属性,而不能修改它们。如果命名窗口定义包含分区、排序或帧属性,则引用该窗口名称的 OVER 子句也不能包含相同类型的属性,否则会发生错误:An OVER clause can only add properties to a
named window, not modify them. 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子句不包含相同类型的属性:This construct is permitted because the window definition and the referringOVERclause do not contain the same kind of properties:OVER (w ORDER BY country) ... WINDOW w AS (PARTITION BY country)
这个构造是不允许的,因为
OVER子句为一个已经具有PARTITION BY的命名窗口指定了PARTITION BY:This construct is not permitted because theOVERclause specifiesPARTITION BYfor a named window that already hasPARTITION BY:OVER (w PARTITION BY year) ... WINDOW w AS (PARTITION BY country)
命名窗口的定义本身可以以window_name开头。在这种情况下,允许前向和后向引用,但不允许循环:The definition of a named window can itself begin with a
window_name. In such cases, forward
and backward references are permitted, but not cycles:
这是允许的;它包含前向和后向引用,但没有循环:This is permitted; it contains forward and backward references but no cycles:
WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)
这是不允许的,因为它包含一个循环:This is not permitted because it contains a cycle:
WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1)