用于窗口函数的窗口定义可以包含一个帧子句。帧是当前分区的一个子集,而帧子句指定如何定义该子集。The definition of a window used with a window function can include a frame clause. A frame is a subset of the current partition and the frame clause specifies how to define the subset.
帧是相对于当前行确定的,这使得帧可以根据当前行在其分区中的位置在分区内移动。示例:Frames are determined with respect to the current row, which enables a frame to move within a partition depending on the location of the current row within its partition. Examples:
通过将帧定义为从分区开始到当前行的所有行,您可以计算每行的累计总和。By defining a frame to be all rows from the partition start to the current row, you can compute running totals for each row.
通过将帧定义为在当前行的两侧各扩展
N行,您可以计算滚动平均值。By defining a frame as extendingNrows on either side of the current row, you can compute rolling averages.
下面的查询演示了使用移动帧在每组按时间排序的level值中计算运行总和,以及从当前行及其前后紧邻的行计算滚动平均值的方法:The following query demonstrates the use of moving frames to
compute running totals within each group of time-ordered
level values, as well as rolling averages
computed from the current row and the rows that immediately
precede and follow it:
mysql>SELECTtime, subject, val,SUM(val) OVER (PARTITION BY subject ORDER BY timeROWS UNBOUNDED PRECEDING)AS running_total,AVG(val) OVER (PARTITION BY subject ORDER BY timeROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)AS running_averageFROM observations;+----------+---------+------+---------------+-----------------+ | time | subject | val | running_total | running_average | +----------+---------+------+---------------+-----------------+ | 07:00:00 | st113 | 10 | 10 | 9.5000 | | 07:15:00 | st113 | 9 | 19 | 14.6667 | | 07:30:00 | st113 | 25 | 44 | 18.0000 | | 07:45:00 | st113 | 20 | 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()会计算可用行的平均值。For the running_average column, there is no
frame row preceding the first one or following the last. In
these cases, AVG() computes the
average of the rows that are available.
作为窗口函数使用的聚合函数在当前行帧中的行上操作,非聚合窗口函数也是如此:Aggregate functions used as window functions operate on rows in the current row frame, as do these nonaggregate window functions:
FIRST_VALUE() LAST_VALUE() NTH_VALUE()
标准 SQL 指定,对整个分区操作的窗口函数不应有帧子句。MySQL 允许这些函数带帧子句,但会忽略它。即使指定了帧,这些函数也会使用整个分区:Standard SQL specifies that window functions that operate on the entire partition should have no frame clause. MySQL permits a frame clause for such functions but ignores it. These functions use the entire partition even if a frame is specified:
CUME_DIST() DENSE_RANK() LAG() LEAD() NTILE() PERCENT_RANK() RANK() ROW_NUMBER()
如果给出了帧子句,其语法如下:The frame clause, if given, has this syntax:
frame_clause:frame_unitsframe_extentframe_units: {ROWS | RANGE}
在没有帧子句的情况下,默认帧取决于是否存在 ORDER BY 子句,如本节后面所述。In the absence of a frame clause, the default frame depends on
whether an ORDER BY clause is present, as
described later in this section.
frame_units 值表示当前行与帧行之间的关系类型:The frame_units value indicates the
type of relationship between the current row and frame rows:
ROWS:帧由起始和结束行位置定义。偏移量是当前行号与帧中行号之间的差值。ROWS: The frame is defined by beginning and ending row positions. Offsets are differences in row numbers from the current row number.RANGE:帧由值范围内的行定义。偏移量是当前行值与帧中行值之间的差值。RANGE: The frame is defined by rows within a value range. Offsets are differences in row values from the current row value.
frame_extent 值表示帧的起点和终点。你可以只指定帧的起点(此时当前行为隐含的终点),或者使用 BETWEEN 来指定帧的两个端点:The frame_extent value indicates the
start and end points of the frame. You can specify just the
start of the frame (in which case the current row is implicitly
the end) or use BETWEEN to specify both frame
endpoints:
frame_extent: {frame_start|frame_between}frame_between: BETWEENframe_startANDframe_endframe_start,frame_end: { CURRENT ROW | UNBOUNDED PRECEDING | UNBOUNDED FOLLOWING |exprPRECEDING |exprFOLLOWING }
使用 BETWEEN 语法时,frame_start 不得晚于 frame_end。With BETWEEN syntax,
frame_start must not occur later than
frame_end.
允许的 frame_start 和 frame_end 值具有以下含义:The permitted frame_start and
frame_end values have these meanings:
CURRENT ROW:对于ROWS,界限为当前行。对于RANGE,界限为当前行的同辈行。CURRENT ROW: ForROWS, the bound is the current row. ForRANGE, the bound is the peers of the current row.UNBOUNDED PRECEDING:界限为分区的第一行。UNBOUNDED PRECEDING: The bound is the first partition row.UNBOUNDED FOLLOWING:界限为分区的最后一行。UNBOUNDED FOLLOWING: The bound is the last partition row.expr PRECEDING:对于ROWS,边界是当前行之前的expr行。对于RANGE,边界是值等于当前行值减去expr的行;如果当前行值为NULL,则边界是该行的同行。: ForexprPRECEDINGROWS, the bound isexprrows before the current row. ForRANGE, the bound is the rows with values equal to the current row value minusexpr; if the current row value isNULL, the bound is the peers of the row.对于
expr PRECEDING(以及expr FOLLOWING),expr可以是?参数标记(用于预处理语句)、非负数字字面值,或者形式为INTERVAL val unit的时间间隔。对于INTERVAL表达式,val指定非负间隔值,unit是一个关键字,表示该值应按何种单位来解释。(有关允许的units指定符的详细信息,请参阅DATE_ADD()函数在 第 14.7 节,“日期和时间函数” 中的描述。)For(andexprPRECEDING),exprFOLLOWINGexprcan be a?parameter marker (for use in a prepared statement), a nonnegative numeric literal, or a temporal interval of the formINTERVAL. ForvalunitINTERVALexpressions,valspecifies nonnegative interval value, andunitis a keyword indicating the units in which the value should be interpreted. (For details about the permittedunitsspecifiers, see the description of theDATE_ADD()function in Section 14.7, “Date and Time Functions”.)RANGE在数值或时间类型的expr上需要对相应的数值或时间表达式使用ORDER BY。RANGEon a numeric or temporalexprrequiresORDER BYon a numeric or temporal expression, respectively.有效的
expr PRECEDING和指示符示例:Examples of validexprFOLLOWINGandexprPRECEDINGindicators:exprFOLLOWING10 PRECEDING INTERVAL 5 DAY PRECEDING 5 FOLLOWING INTERVAL '2:30' MINUTE_SECOND FOLLOWING
expr FOLLOWING:对于ROWS,边界为当前行之后的expr行。对于RANGE,边界为值等于当前行值加上expr的行;如果当前行值为NULL,则边界为该行的同行。: ForexprFOLLOWINGROWS, the bound isexprrows after the current row. ForRANGE, the bound is the rows with values equal to the current row value plusexpr; if the current row value isNULL, the bound is the peers of the row.有关允许的
expr值,请参阅expr PRECEDING的说明。For permitted values ofexpr, see the description of.exprPRECEDING
下面的查询演示了 FIRST_VALUE()、LAST_VALUE() 以及两个 NTH_VALUE() 的用例:The following query demonstrates
FIRST_VALUE(),
LAST_VALUE(), and two instances
of NTH_VALUE():
mysql>SELECTtime, 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 observationsWINDOW w AS (PARTITION BY subject ORDER BY timeROWS UNBOUNDED PRECEDING);+----------+---------+------+-------+------+--------+--------+ | time | subject | val | first | last | second | fourth | +----------+---------+------+-------+------+--------+--------+ | 07:00:00 | st113 | 10 | 10 | 10 | NULL | NULL | | 07:15:00 | st113 | 9 | 10 | 9 | 9 | NULL | | 07:30:00 | st113 | 25 | 10 | 25 | 9 | NULL | | 07:45:00 | st113 | 20 | 10 | 20 | 9 | 20 | | 07:00:00 | xh458 | 0 | 0 | 0 | NULL | NULL | | 07:15:00 | xh458 | 10 | 0 | 10 | 10 | NULL | | 07:30:00 | xh458 | 5 | 0 | 5 | 10 | NULL | | 07:45:00 | xh458 | 30 | 0 | 30 | 10 | 30 | | 08:00:00 | xh458 | 25 | 0 | 25 | 10 | 30 | +----------+---------+------+-------+------+--------+--------+
每个函数使用当前框架中的行,根据所示的窗口定义,该框架从第一个分区行延伸到当前行。对于 NTH_VALUE() 调用,当前框架并不总是包含请求的行;在这种情况下,返回值为 NULL。Each function uses the rows in the current frame, which, per the
window definition shown, extends from the first partition row to
the current row. For the
NTH_VALUE() calls, the current
frame does not always include the requested row; in such cases,
the return value is NULL.
如果没有指定 frame 子句,默认的 frame 取决于是否存在 ORDER BY 子句:In the absence of a frame clause, the default frame depends on
whether an ORDER BY clause is present:
有
ORDER BY:默认的 frame 包括从分区开始到当前行的所有行,包括当前行的所有 peers(根据ORDER BY子句与当前行相等的行)。默认值等效于以下 frame 规格:WithORDER BY: The default frame includes rows from the partition start through the current row, including all peers of the current row (rows equal to the current row according to theORDER BYclause). The default is equivalent to this frame specification:RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
没有
ORDER BY:默认的 frame 包括所有分区行(因为没有ORDER BY时,所有分区行都是 peers)。默认值等效于以下 frame 规格:WithoutORDER BY: The default frame includes all partition rows (because, withoutORDER BY, all partition rows are peers). The default is equivalent to this frame specification:RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
由于默认帧会根据是否存在 ORDER BY 而有所不同,因此在查询中添加 ORDER BY 以获得确定性结果可能会改变结果。(例如,由 SUM() 生成的值可能会发生变化。)为了获得相同的结果,但按 ORDER BY 排序,请提供一个明确的帧规范,无论是否存在 ORDER
BY 都使用该规范。Because the default frame differs depending on presence or
absence of ORDER BY, adding ORDER
BY to a query to get deterministic results may change
the results. (For example, the values produced by
SUM() might change.) To obtain
the same results but ordered per ORDER BY,
provide an explicit frame specification to be used regardless of
whether ORDER BY is present.
当当前行值为 NULL 时,帧规范的含义可能不明显。在这种假设下,这些示例说明了各种帧规范的应用方式:The meaning of a frame specification can be nonobvious when the
current row value is NULL. Assuming that to
be the case, these examples illustrate how various frame
specifications apply:
ORDER BY X ASC RANGE BETWEEN 10 FOLLOWING AND 15 FOLLOWING帧从
NULL开始,到NULL结束,因此只包含值为NULL的行。The frame starts atNULLand stops atNULL, thus includes only rows with valueNULL.ORDER BY X ASC RANGE BETWEEN 10 FOLLOWING AND UNBOUNDED FOLLOWING帧从
NULL开始,到分区末尾结束。因为ASC排序将NULL值放在最前面,所以帧为整个分区。The frame starts atNULLand stops at the end of the partition. Because anASCsort putsNULLvalues first, the frame is the entire partition.ORDER BY X DESC RANGE BETWEEN 10 FOLLOWING AND UNBOUNDED FOLLOWING帧从
NULL开始,到分区末尾结束。因为DESC排序将NULL值放在最后,所以帧只包含NULL值。The frame starts atNULLand stops at the end of the partition. Because aDESCsort putsNULLvalues last, the frame is only theNULLvalues.ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND UNBOUNDED FOLLOWINGORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND UNBOUNDED FOLLOWING帧从
NULL开始,到分区末尾结束。因为ASC排序将NULL值放在最前面,所以帧为整个分区。The frame starts atNULLand stops at the end of the partition. Because anASCsort putsNULLvalues first, the frame is the entire partition.ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 10 FOLLOWINGORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 10 FOLLOWING帧从
NULL开始,到NULL结束,因此只包含值为NULL的行。The frame starts atNULLand stops atNULL, thus includes only rows with valueNULL.ORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 1 PRECEDINGORDER BY X ASC RANGE BETWEEN 10 PRECEDING AND 1 PRECEDING帧从
NULL开始,到NULL结束,因此只包含值为NULL的行。The frame starts atNULLand stops atNULL, thus includes only rows with valueNULL.ORDER BY X ASC RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWINGORDER BY X ASC RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING帧从分区的开始处开始,并在值为
NULL的行处停止。因为ASC排序会将NULL值放在最前面,所以帧仅包含NULL值。The frame starts at the beginning of the partition and stops at rows with valueNULL. Because anASCsort putsNULLvalues first, the frame is only theNULLvalues.