文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

14.20.4 命名窗口14.20.4 Named Windows

可以在 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:

WINDOW window_name AS (window_spec)
    [, window_name AS (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 (window_name ...) rather than OVER window_name, the named window can be modified by the addition of other clauses. 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:

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 referring OVER clause 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 the OVER clause specifies PARTITION BY for a named window that already has PARTITION 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)