与窗口函数一起使用的窗口的定义可以包含一个frame子句。帧是当前分区的子集,帧子句指定如何定义这个子集。
帧是根据当前行确定的,这使得帧可以根据当前行在分区中的位置在分区中移动。例子:
通过将一个帧定义为从分区开始到当前行的所有行,您可以计算每一行的运行总数。
通过将框架定义为扩展
N
在当前行的两侧,可以计算滚动平均。
下面的查询演示了如何使用移动帧来计算每组时间顺序的运行总数水平
值,以及从当前行和紧接在它前面和后面的行计算的滚动平均值:
mysql> SELECT time, subject, val, SUM(val) OVER (PARTITION BY subject ORDER BY time ROWS UNBOUNDED previous) AS running_total, AVG(val) OVER (PARTITION BY subject ORDER BY time ROWS BETWEEN 1 previous AND 1 FOLLOWING) AS running_average FROM observations;+----------+---------+------+---------------+-----------------+ | 时间| |主题val | running_total | running_average | +----------+---------+------+---------------+-----------------+ | 07:00:00 | st113 | 10 | | 9.5000 | | 07:15:00 | st113 | 9 19 | | 14.6667 | | 07:30:00 | st113 | 25 44 | | 18.0000 | | 07:45:00 | st113 | 64 | | 22.5000 | | 07:00:00 | xh458 | 0 | 0 | 5.0000 | | 07:15:00 | xh458 | 10 | | 5.0000 | | 07:30:00 | xh458 | 5 | 15 | 15.0000 | | 07:45:00 | xh458 30 45 | | |20.0000 | | 08:00:00 | xh458 25 | 70 | 27.5000 | | +----------+---------+------+---------------+-----------------+
为running_average
列时,第一行之前或最后一行之后都没有帧行。在这些情况下,AVG ()
计算可用行的平均值。
用作窗口函数的聚合函数操作当前行帧中的行,这些非聚合窗口函数也是如此:
First_value () last_value ()
标准SQL指定操作整个分区的窗口函数不应该有frame子句。MySQL允许这类函数使用frame子句,但忽略了它。这些函数使用整个分区,即使指定了一个帧:
Cume_dist () dense_rank () lag () lead () ntile () percent_rank () rank () row_number ()
如果给出了frame子句,它的语法如下:
frame_clause:frame_unitsframe_extentframe_units: {rows | range}
在没有框架子句的情况下,默认的框架取决于是否使用命令
子句存在,如本节后面所述。
的frame_units
Value表示当前行和帧行之间的关系类型:
行
:帧由开始行和结束行位置定义。偏移量是行号与当前行号之间的差异。范围
:帧由值范围内的行定义。偏移量是行值与当前行值之间的差异。
的frame_extent
值表示帧的起始点和结束点。您可以只指定帧的开始(在这种情况下,当前行隐式地是结束)或使用之间的
指定两个帧端点:
frame_extent: {frame_start|frame_between}frame_between间:frame_start和frame_endframe_start,frame_end:{当前行|前|后|无界expr前|expr后}
与之间的
语法,frame_start
不能晚于frame_end
.
允许frame_start
而且frame_end
价值观有以下含义:
当前行
:对于行
,边界为当前行。为范围
,界为当前行的对等点。无限的前
:边界为分区的第一行。无界后
:边界为分区的最后一行。
:对于expr
前行
,界为expr
当前行之前的行。为范围
,界是值等于当前行值减去的行expr
;如果当前行值为零
,界是行的对等点。为
(和expr
前
),expr
后expr
可以是?
参数标记(用于预备语句)、非负数值文字或形式的时间间隔时间间隔
.为瓦尔
单位
时间间隔
表情,瓦尔
指定非负的间隔值,和单位
是指示应该在其中解释值的单位的关键字。(详情请参阅单位
说明符,请参见说明DATE_ADD ()
函数第12.7节“日期和时间函数”.)范围
在数字或时间上expr
需要命令
在数值表达式或时间表达式上。有效的例子
而且expr
前
指标:expr
后10 before interval 5 before 5 following interval '2:30' minute_second
:对于expr
后行
,界为expr
当前行之后的行。为范围
,界是值等于当前行值加的行expr
;如果当前行值为零
,界是行的对等点。的容许值
expr
,见描述
.expr
前
下面的查询演示了FIRST_VALUE ()
,LAST_VALUE ()
的两个实例NTH_VALUE ()
:
mysql> SELECT time, subject, val, FIRST_VALUE(val) OVER w AS 'first', LAST_VALUE(val) OVER w AS 'last', NTH_VALUE(val, 2) OVER w AS 'second', NTH_VALUE(val, 4) OVER w AS 'fourth' FROM观察窗口w AS(按主题顺序按时间行划分);+----------+---------+------+-------+------+--------+--------+ | 时间| |主题首先val | | |第二|第四 | +----------+---------+------+-------+------+--------+--------+ | 07:00:00 | st113 | 10 10 | | |空零| | | 07:15:00 | st113 | 9 | 10 | 9 | 9零| | | 07:30:00 | st113 25 | | 10 | 25 | 9零| | | 07:45:00 | st113 20 | | 10 | 20 | 9 | 20 | | 07:00:00 | xh458 | 0 | 0 | 0 |空零| | | 07:15:00 | xh458 | 10 | 0 | 10 | |零| | 07:30:00 | xh458 | 5 | 0 | 5 | 10|零||07:45:00 | xh458 | 30 | 0 | 30 | 10 | 30 | | 08:00:00 | xh458 | 25 | 0 | 25 | 10 | 30 | +----------+---------+------+-------+------+--------+--------+
每个函数都使用当前帧中的行,根据所示的窗口定义,当前帧从第一个分区行扩展到当前行。为NTH_VALUE ()
调用时,当前帧并不总是包含所请求的行;在这种情况下,返回值为零
.
在没有框架子句的情况下,默认的框架取决于是否使用命令
子句存在:
与
命令
:默认帧包括从分区开始到当前行的行,包括当前行的所有对等体(根据命令
条款)。默认值相当于这个帧规范:前一行和当前行之间的无界范围
没有
命令
:默认帧包括所有分区行(因为,没有命令
,所有的分区行都是对等体)。默认值相当于这个帧规范:介于无界前和无界后之间
的存在或不存在会导致默认帧的不同命令
,添加命令
查询以获得确定性结果可能会更改结果。(例如,产生的值SUM ()
可能会改变)。得到相同的结果,但顺序是命令
,提供要使用的显式框架规范,无论是否命令
是礼物。
当当前行值为时,帧规范的含义可能不明显零
.假设是这样,这些例子说明了各种框架规范是如何应用的:
订购x asc范围在10以下和15以下
帧开始于
零
停在零
,因此只包含有值的行零
.顺序由x asc范围在10以下和无界以下
帧开始于
零
并在分区的末端停止。因为一个ASC
排序了零
值首先,帧是整个分区。根据x desc的顺序,从10个跟随到无界跟随
帧开始于
零
并在分区的末端停止。因为一个DESC
排序了零
值最后,帧只有零
值。顺序由x asc范围在前10和后无界之间
帧开始于
零
并在分区的末端停止。因为一个ASC
排序了零
值首先,帧是整个分区。订购x asc范围在前10和后10之间
帧开始于
零
停在零
,因此只包含有值的行零
.订购x asc范围在10之前和1之前
帧开始于
零
停在零
,因此只包含有值的行零
.顺序由x asc范围在无界的前面和10后面
该框架从分区的开始处开始,并在有值的行处停止
零
.因为一个ASC
排序了零
值第一,帧只有零
值。