MySQL命名窗口及窗口函数的限制

刺骨的言语ヽ痛彻心扉 2022-03-27 11:14 458阅读 0赞

原文地址:

https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html

https://dev.mysql.com/doc/refman/8.0/en/window-function-restrictions.html

译文:

12.21.4 Named Windows

窗口可以被定义和给定能够在OVER语句中引用该窗口的名称。为此,可以使用WINDOW语句。如果在查询中出现,WINDOW语句位于HAVING和ORDER BY语句之间,语法如下:

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

对于每个窗口定义,window_name是窗口名,而window_spec与OVER语句圆括号中给出的窗口说明类型相同,如 Section 12.21.2, “Window Function Concepts and Syntax”中所述:

  • window_spec:
    1. [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;

想要更简单地编写上述查询,只需使用窗口定义一次窗口,并在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);

一个命名的窗口还可以简化对窗口定义的试验,以查看对查询结果的影响。我们只需要修改window语句中的窗口定义,而不是在多个OVER语句中对窗口进行重新定义。

如果OVER语句使用OVER (window_name…)而不是OVER window_name,则可以通过添加其他子句来修改命名的窗口。例如,下面这个查询定义了一个包含分区的窗口,并在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);

OVER语句只能向命名窗口中添加属性,而不能修改它们。如果命名的窗口定义包含分区、排序或框架属性,则引用该窗口名称的OVER语句也不能包含相同类型的属性,否则将发生错误:

  1. 1)下面这个结构是允许的,因为窗口定义和引用窗口的OVER语句不包含相同类型的属性:
  • OVER (w ORDER BY country)
    … WINDOW w AS (PARTITION BY country)

    2)下面这个结构是不允许的,因为OVER语句为一个已经有PARTITION BY的命名窗口指定了PARTITION BY:

  • OVER (w PARTITION BY year)
    … WINDOW w AS (PARTITION BY country)

已命名窗口的定义本身可以以window_name开头。在这种情况下,允许向前和向后引用,但不允许循环:

  1. 1)这是允许的;它包含向前和向后引用,但没有循环:
  • WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)

    2)这是不允许的,因为它包含一个循环:

  • WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1)

~~~~~~我是分割线~~~~~~~~~

12.21.5 Window Function Restrictions

SQL标准对窗口函数施加了约束,这些函数不能在UPDATE或DELETE语句中用于更新行。允许在这些语句的子查询中使用这些函数(选择行)。

MySQL不支持以下窗口函数特性:

  1. 1DISTINCT语法用于聚合式窗口函数;
  2. 2)嵌套窗口函数;
  3. 3)依赖于当前行的值的动态框架端点。

解析器可以识别这些窗口结构,但它们不被支持:

  1. 1GROUPS框架单位说明符可以被解析,但会产生一个错误。只支持ROWSRANGE
  2. 2)用于框架说明的EXCLUDE语句可以被解析,但会产生一个错误;
  3. 3IGNORE NULLS可以被解析,但会产生一个错误。只支持RESPECT NULLS
  4. 4FROM LAST可以被解析,但会产生一个错误。只支持FROM FIRST

PS:由于水平有限,译文中难免存在谬误,欢迎批评指正。

发表评论

表情:
评论列表 (有 0 条评论,458人围观)

还没有评论,来说两句吧...

相关阅读

    相关 MySQL窗口函数

    从version 8.0开始,MySQL支持在查询中使用窗口函数。这篇文章是对一篇英文资料的不完全翻译,加上自己的一些理解。如果有兴趣可以去看看原文章。文中的示例用到的建表语句