与窗口函数一起使用的窗口的定义可以包括帧子句。帧是当前分区的子集,框架子句指定如何定义子集。
相对于当前行确定帧,这使得帧能够根据其分区内的当前行的位置而在分区内移动。例子:
通过定义一个帧为从分区开始到当前行的所有行,可以计算每一行的运行总数。
通过将框架定义为扩展
N
行在当前行的任何一边,您可以计算滚动平均。
下面的查询演示了如何使用移动帧来计算每一组按时间顺序排列的总数水平
值以及从当前行计算的滚动平均值和紧接在其前后的行:
mysql> SELECT time, subject, val, SUM(val) OVER (PARTITION BY subject ORDER BY time ROWS UNBOUNDED before) AS running_total, AVG(val) OVER (PARTITION BY subject ORDER BY time ROWS BETWEEN 1 before 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 | 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()
计算可用行的平均值。
作为窗口函数使用的聚合函数对当前行帧中的行进行操作,这些非聚合窗口函数也是如此:
NTH_VALUE LAST_VALUE FIRST_VALUE () () ()
标准SQL规定,在整个分区上操作的窗口函数不应该有框架子句。MySQL允许这样的函数有一个框架子句,但是忽略它。即使指定了帧,这些函数也会使用整个分区:
cme_dist () dense_rank () lag () lead () ntile () percent_rank () rank () row_number ()
如果给出框架子句,它的语法如下:
frame_clause:Frame_Units.frame_extent.Frame_Units.:{行|范围}
在没有框架子句的情况下,默认帧取决于是否是一个订购
条款存在,如本节后面所述。
这Frame_Units.
值表示当前行和帧行之间的关系类型:
行
:该帧由开始和结束行位置定义。偏移量是来自当前行号的行号中的差异。范围
:帧由值范围内的行定义。偏移量是行值与当前行值的差异。
这frame_extent.
Value表示帧的开始和结束点。您可以指定帧的开始(在这种情况下,当前行是隐式的结束)或使用之间
要指定帧端点:
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
可以是A.?
参数标记(用于准备的语句),非负数字文字或表单的时间间隔间隔
。为了瓦尔
单位
间隔
表达,瓦尔
指定非负区间值和单位
是一个关键字,指示应该解释该值的单位。(有关允许的详细信息单位
说明符,请参阅描述的描述DATE_ADD ()
函数第12.7节“日期和时间函数”。)范围
在数字或时间上expr
需要订购
分别在数值表达式或时态表达式上。有效的例子
和expr
前
指标:expr
后前10个间隔后5天前5个间隔后2:30分秒后
: 为了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 observations w AS w AS (PARTITION BY subject ORDER BY time ROWS UNBOUNDED before);+----------+---------+------+-------+------+--------+--------+ | 时间| |主题首先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 30 | | 0 | | 10 | 30 | | 08:00:00 | xh458 25 | 0 | | 25 | 10 | 30 | +----------+---------+------+-------+------+--------+--------+
每个函数都使用当前帧中的行,每个函数根据所示的窗口定义,从第一分区行扩展到当前行。为了nth_value()
调用时,当前帧并不总是包含所请求的行;在这种情况下,返回值为零
。
在没有框架子句的情况下,默认帧取决于是否是一个订购
条款存在:
和
订购
:默认框架包括从分区的行通过当前行开始,包括当前行的所有对等体(根据当前行的行等于当前行订购
条款)。默认值相当于此帧规范:前行和当前行之间的范围
没有
订购
:默认帧包括所有分区行(因为,没有订购
,所有分区行都是对等体)。默认值相当于此帧规范:范围在无界面的前面和无界限下面
因为默认帧根据是否存在而不同订购
,加倍订购
向查询获取确定性结果可能会更改结果。(例如,生成的值和()
可能会改变)。以获得相同的结果,但顺序为订购
,提供一个明确的框架规范,无论是否使用订购
存在。
当当前行值为时,帧规范的含义可能不明显零
。假设是这样,这些例子说明了各种框架规范是如何应用的:
按X ASC范围为10以下和15以下
框架开始了
零
并停止零
,因此只包含有值的行零
。x asc的顺序范围在10跟随和无界跟随之间
框架开始了
零
停在分区的末端。因为一个ASC.
排序了零
值首先,框架是整个分区。根据x desc的顺序范围在10跟随和无界跟随之间
框架开始了
零
停在分区的末端。因为A.去世
排序了零
值最后,帧只是零
价值观。x asc的顺序范围在10之前和无界之后
框架开始了
零
停在分区的末端。因为一个ASC.
排序了零
值首先,框架是整个分区。按x asc顺序排列,前10和后10之间
框架开始了
零
并停止零
,因此只包含有值的行零
。按x asc排序的范围在前面10和前面1之间
框架开始了
零
并停止零
,因此只包含有值的行零
。前面的无界和后面的10之间的顺序
帧在分区的开头开始,并在带有值的行停止
零
。因为一个ASC.
排序了零
首先,帧只是零
价值观。