暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL的函数和运算符 - 窗口函数 - 命名窗口

林员外聊编程 2021-09-26
205
命名窗口
 
可以定义窗口并给定名称,在 OVER 子句可以引用这些窗口名。为此,请使用 WINDOW 子句。如果查询中存在 WINDOW 子句,则它位于 HAVING 子句和 ORDER BY 子句之间,语法如下:
 
WINDOW window_name AS (window_spec)
    [, window_name AS (window_spec)] ...
 
对于每个窗口定义,window_name 是窗口名,window_spec 是与 OVER 子句圆括号中给出的相同类型的窗口规范:
 
window_spec:
[window_name] [partition_clause] [order_clause] [frame_clause]
 
对于多个 OVER 子句定义相同窗口的查询,WINDOW 子句非常有用。可以定义一次窗口,给它一个名称,然后在 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;
 
通过使用 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);
 
有名称的窗口还可以更容易地试验窗口定义,以查看对查询结果的影响。只需要修改 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 子句不能也包含相同类型的属性,否则就会发生错误:
 
● 这种结构是允许的,因为窗口定义和引用窗口的 OVER 子句不包含相同类型的属性:
 
OVER (w ORDER BY country)
... WINDOW w AS (PARTITION BY country)
 
● 这个结构是不允许的,因为 OVER 子句为已经有 PARTITION BY 的命名窗口指定了 PARTITION BY
 
OVER (w PARTITION BY year)
... WINDOW w AS (PARTITION BY country)
 
命名窗口的定义本身可以以 window_name 开头。在这种情况下,允许向前和向后引用,但不允许循环引用:
 
● 允许这种形式,它包含正向和反向引用,但没有循环引用:
 
WINDOW w1 AS (w2), w2 AS (), w3 AS (w1)
 
● 不允许这种情况,因为它包含一个循环引用:
 
WINDOW w1 AS (w2), w2 AS (w3), w3 AS (w1)
 
 
 
 
 
官方网址:
https://dev.mysql.com/doc/refman/8.0/en/window-functions-named-windows.html
文章转载自林员外聊编程,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论