12.21.3 Window Function Frame Specification窗口函数框规范

The definition of a window used with a window function can include a frame clause. 与窗口函数一起使用的窗口的定义可以包括frame子句。A frame is a subset of the current partition and the frame clause specifies how to define the subset.frame是当前分区的子集,frame子句指定如何定义子集。

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:示例:

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:下面的查询演示如何使用移动框来计算每组按时间顺序排列的level值中的运行总计,以及从当前行以及紧跟在当前行之前和之后的行计算的滚动平均值:

mysql> SELECT
time, subject, val,
SUM(val) OVER (PARTITION BY subject ORDER BY time
ROWS UNBOUNDED PRECEDING)
AS running_total,
AVG(val) OVER (PARTITION BY subject ORDER BY time
ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
AS running_average
FROM 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 |
+----------+---------+------+---------------+-----------------+

For the running_average column, there is no frame row preceding the first one or following the last. 对于running_average列,在第一个列之前或最后一个列之后没有框行。In these cases, AVG() computes the average of the rows that are available.在这些情况下,AVG()计算可用行的平均值。

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()

Standard SQL specifies that window functions that operate on the entire partition should have no frame clause. 标准SQL指定在整个分区上操作的窗口函数不应有frame子句。MySQL permits a frame clause for such functions but ignores it. These functions use the entire partition even if a frame is specified:MySQL允许为这些函数使用frame子句,但忽略了它。即使指定了框,这些函数也使用整个分区:

CUME_DIST()
DENSE_RANK()
LAG()
LEAD()
NTILE()
PERCENT_RANK()
RANK()
ROW_NUMBER()

The frame clause, if given, has this syntax:frame子句(如果给定)具有以下语法:

frame_clause:
frame_units frame_extent
frame_units:
    {ROWS | RANGE}

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子句的情况下,默认的frame取决于是否存在ORDER BY子句,如本节后面所述。

The frame_units value indicates the type of relationship between the current row and frame rows:frame_units值表示当前行和框行之间的关系类型:

The frame_extent value indicates the start and end points of the frame. frame_extent值指示框的起点和终点。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:您可以仅指定框的开始(在这种情况下,当前行隐式地为结束)或使用BETWEEN指定两个框端点:

frame_extent:
    {frame_start | frame_between}
frame_between:
    BETWEEN frame_start AND frame_end
frame_start, frame_end: {
    CURRENT ROW
  | UNBOUNDED PRECEDING
  | UNBOUNDED FOLLOWING
  | expr PRECEDING
  | expr FOLLOWING
}

With BETWEEN syntax, frame_start must not occur later than frame_end.对于BETWEEN语法,frame_start不能晚于frame_end

The permitted frame_start and frame_end values have these meanings:允许的frame_startframe_end值具有以下含义:

The following query demonstrates FIRST_VALUE(), LAST_VALUE(), and two instances of NTH_VALUE():下面的查询演示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
WINDOW w AS (PARTITION BY subject ORDER BY time
ROWS 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 |
+----------+---------+------+-------+------+--------+--------+

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.对于第n个VALUE()调用,当前框并不总是包含请求的行;在这种情况下,返回值为NULL

In the absence of a frame clause, the default frame depends on whether an ORDER BY clause is present:如果没有框架子句,则默认框架取决于是否存在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. 由于默认框因是否存在ORDER BY而不同,因此向查询中添加ORDER BY以获得确定性结果可能会更改结果。(For example, the values produced by SUM() might change.) (例如,SUM()生成的值可能会更改。)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.若要获得相同的结果但按ORDER BY排序,请提供一个无论ORDER BY是否存在都要使用的显式框规范。

The meaning of a frame specification can be nonobvious when the current row value is NULL. 当当前行值为NULL时,框规范的含义可能不明显。Assuming that to be the case, these examples illustrate how various frame specifications apply:假设是这样,这些示例说明了各种框架规范是如何应用的: