本节描述了非聚合窗口函数,这些函数针对查询中的每一行,使用与该行相关的行执行计算。大多数聚合函数也可以用作窗口函数;参见第 14.19.1 节,“聚合函数描述”。This section describes nonaggregate window functions that, for each row from a query, perform a calculation using rows related to that row. Most aggregate functions also can be used as window functions; see Section 14.19.1, “Aggregate Function Descriptions”.
有关窗口函数的使用信息和示例,以及诸如OVER子句、窗口、分区、帧和同行等术语的定义,请参见第 14.20.2 节,“窗口函数概念与语法”。For window function usage information and examples, and
definitions of terms such as the OVER clause,
window, partition, frame, and peer, see
Section 14.20.2, “Window Function Concepts and Syntax”.
表 14.30 窗口函数Table 14.30 Window Functions
| 名称Name | 说明Description |
|---|---|
CUME_DIST() |
累计分布值Cumulative distribution value |
DENSE_RANK() |
当前行在其分区内的排名,无间隙Rank of current row within its partition, without gaps |
FIRST_VALUE() |
窗口框第一行的参数值Value of argument from first row of window frame |
LAG() |
分区内滞后当前行的行的参数值Value of argument from row lagging current row within partition |
LAST_VALUE() |
窗口框最后一行的参数值Value of argument from last row of window frame |
LEAD() |
分区内前一行的行值参数Value of argument from row leading current row within partition |
NTH_VALUE() |
来自窗口框第 N 行的参数值Value of argument from N-th row of window frame |
NTILE() |
当前行在其分区内的桶编号。Bucket number of current row within its partition. |
PERCENT_RANK() |
百分比排名值Percentage rank value |
RANK() |
当前行在其分区内的排名,允许有空缺Rank of current row within its partition, with gaps |
ROW_NUMBER() |
当前行在其分区内的编号Number of current row within its partition |
在以下函数描述中,over_clause 表示 OVER 子句,如 第 14.20.2 节,“窗口函数概念和语法” 所述。一些窗口函数允许使用 null_treatment 子句来指定在计算结果时如何处理 NULL 值。该子句是可选的。它是 SQL 标准的一部分,但 MySQL 实现仅允许 RESPECT NULLS(这也是默认值)。这意味着在计算结果时会考虑 NULL 值。IGNORE NULLS 会被解析,但会产生错误。In the following function descriptions,
over_clause represents the
OVER clause, described in
Section 14.20.2, “Window Function Concepts and Syntax”. Some window functions
permit a null_treatment clause that
specifies how to handle NULL values when
calculating results. This clause is optional. It is part of the
SQL standard, but the MySQL implementation permits only
RESPECT NULLS (which is also the default).
This means that NULL values are considered
when calculating results. IGNORE NULLS is
parsed, but produces an error.
CUME_DIST()over_clause返回一组值中某个值的累积分布;即小于或等于当前行中值的分区值的百分比。这表示窗口分区中窗口排序中当前行之前或与当前行同行的行数除以窗口分区中的总行数。返回值范围从 0 到 1。Returns the cumulative distribution of a value within a group of values; that is, the percentage of partition values less than or equal to the value in the current row. This represents the number of rows preceding or peer with the current row in the window ordering of the window partition divided by the total number of rows in the window partition. Return values range from 0 to 1.
此函数应与
ORDER BY一起使用,以将分区行按所需顺序排序。如果没有ORDER BY,所有行都是同等的,其值为N/N= 1,其中N是分区大小。This function should be used withORDER BYto sort partition rows into the desired order. WithoutORDER BY, all rows are peers and have valueN/N= 1, whereNis the partition size.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.以下查询显示了,对于
val列中的值集合,每行的CUME_DIST()值,以及类似函数PERCENT_RANK()返回的百分比排名值。作为参考,该查询还使用ROW_NUMBER()显示行号:The following query shows, for the set of values in thevalcolumn, theCUME_DIST()value for each row, as well as the percentage rank value returned by the similarPERCENT_RANK()function. For reference, the query also displays row numbers usingROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',CUME_DIST() OVER w AS 'cume_dist',PERCENT_RANK() OVER w AS 'percent_rank'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+--------------------+--------------+ | val | row_number | cume_dist | percent_rank | +------+------------+--------------------+--------------+ | 1 | 1 | 0.2222222222222222 | 0 | | 1 | 2 | 0.2222222222222222 | 0 | | 2 | 3 | 0.3333333333333333 | 0.25 | | 3 | 4 | 0.6666666666666666 | 0.375 | | 3 | 5 | 0.6666666666666666 | 0.375 | | 3 | 6 | 0.6666666666666666 | 0.375 | | 4 | 7 | 0.8888888888888888 | 0.75 | | 4 | 8 | 0.8888888888888888 | 0.75 | | 5 | 9 | 1 | 1 | +------+------------+--------------------+--------------+DENSE_RANK()over_clause返回当前行在其分区内的排名,不存在间隙。同行被视为并列并获得相同的排名。该函数为同行组分配连续排名;结果是,大小大于一的组不会产生不连续的排名数字。示例请参见
RANK()函数说明。Returns the rank of the current row within its partition, without gaps. Peers are considered ties and receive the same rank. This function assigns consecutive ranks to peer groups; the result is that groups of size greater than one do not produce noncontiguous rank numbers. For an example, see theRANK()function description.该函数应与
ORDER BY一起使用,以将分区行排序为所需的顺序。如果没有ORDER BY,所有行都被认为是同行。This function should be used withORDER BYto sort partition rows into the desired order. WithoutORDER BY, all rows are peers.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.FIRST_VALUE([expr)null_treatment]over_clause返回窗口帧第一行的
expr的值。Returns the value ofexprfrom the first row of the window frame.over_clause的说明请参见 第 14.20.2 节,“窗口函数概念与语法”。null_treatment的说明请参见本节介绍部分。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.null_treatmentis as described in the section introduction.下面的查询演示了
FIRST_VALUE()、LAST_VALUE()以及两个NTH_VALUE()的用例:The following query demonstratesFIRST_VALUE(),LAST_VALUE(), and two instances ofNTH_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 theNTH_VALUE()calls, the current frame does not always include the requested row; in such cases, the return value isNULL.LAG([expr[,N[,default]])null_treatment]over_clause返回分区内滞后(前置)当前行
N行的expr的值。如果不存在这样的行,返回值为default。例如,如果N为 3,则前三行的返回值为default。如果缺少N或default,默认值分别为 1 和NULL。Returns the value ofexprfrom the row that lags (precedes) the current row byNrows within its partition. If there is no such row, the return value isdefault. For example, ifNis 3, the return value isdefaultfor the first three rows. IfNordefaultare missing, the defaults are 1 andNULL, respectively.N必须是字面上的非负整数。如果N为 0,则expr会对当前行进行评估。Nmust be a literal nonnegative integer. IfNis 0,expris evaluated for the current row.N不能为NULL,并且必须是以下任一形式中从0到263(含)范围内的整数:Ncannot beNULL, and must be an integer in the range0to263, inclusive, in any of the following forms:无符号整数常量字面值an unsigned integer constant literal
一个位置参数标记 (
?)a positional parameter marker (?)用户定义的变量a user-defined variable
存储过程中的局部变量a local variable in a stored routine
over_clause的说明请参见 第 14.20.2 节,“窗口函数概念与语法”。null_treatment的说明请参见本节介绍部分。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.null_treatmentis as described in the section introduction.LAG()(以及类似的LEAD()函数)常用于计算行之间的差异。以下查询显示了一组按时间排序的观测值,并且对于每一个观测值,显示相邻行的LAG()和LEAD()值,以及当前行与相邻行之间的差异:LAG()(and the similarLEAD()function) are often used to compute differences between rows. The following query shows a set of time-ordered observations and, for each one, theLAG()andLEAD()values from the adjoining rows, as well as the differences between the current and adjoining rows:mysql>
SELECTt, val,LAG(val) OVER w AS 'lag',LEAD(val) OVER w AS 'lead',val - LAG(val) OVER w AS 'lag diff',val - LEAD(val) OVER w AS 'lead diff'FROM seriesWINDOW w AS (ORDER BY t);+----------+------+------+------+----------+-----------+ | t | val | lag | lead | lag diff | lead diff | +----------+------+------+------+----------+-----------+ | 12:00:00 | 100 | NULL | 125 | NULL | -25 | | 13:00:00 | 125 | 100 | 132 | 25 | -7 | | 14:00:00 | 132 | 125 | 145 | 7 | -13 | | 15:00:00 | 145 | 132 | 140 | 13 | 5 | | 16:00:00 | 140 | 145 | 150 | -5 | -10 | | 17:00:00 | 150 | 140 | 200 | 10 | -50 | | 18:00:00 | 200 | 150 | NULL | 50 | NULL | +----------+------+------+------+----------+-----------+在示例中,
LAG()和LEAD()调用分别使用默认的N和default值,即 1 和NULL。In the example, theLAG()andLEAD()calls use the defaultNanddefaultvalues of 1 andNULL, respectively.第一行显示了当
LAG()没有前一行时会发生什么:函数返回default值(在本例中为NULL)。最后一行显示了当LEAD()没有下一行时同样的情况。The first row shows what happens when there is no previous row forLAG(): The function returns thedefaultvalue (in this case,NULL). The last row shows the same thing when there is no next row forLEAD().LAG()和LEAD()也可以用来计算和而不是差。考虑这个数据集,它包含了斐波那契数列的前几个数字:LAG()andLEAD()also serve to compute sums rather than differences. Consider this data set, which contains the first few numbers of the Fibonacci series:mysql>
SELECT n FROM fib ORDER BY n;+------+ | n | +------+ | 1 | | 1 | | 2 | | 3 | | 5 | | 8 | +------+下面的查询显示了当前行相邻行的
LAG()和LEAD()值。它还使用这些函数将前一行和下一行的值加到当前行的值上。效果是生成斐波那契数列中的下一个数字,以及其后的下一个数字:The following query shows theLAG()andLEAD()values for the rows adjacent to the current row. It also uses those functions to add to the current row value the values from the preceding and following rows. The effect is to generate the next number in the Fibonacci series, and the next number after that:mysql>
SELECTn,LAG(n, 1, 0) OVER w AS 'lag',LEAD(n, 1, 0) OVER w AS 'lead',n + LAG(n, 1, 0) OVER w AS 'next_n',n + LEAD(n, 1, 0) OVER w AS 'next_next_n'FROM fibWINDOW w AS (ORDER BY n);+------+------+------+--------+-------------+ | n | lag | lead | next_n | next_next_n | +------+------+------+--------+-------------+ | 1 | 0 | 1 | 1 | 2 | | 1 | 1 | 2 | 2 | 3 | | 2 | 1 | 3 | 3 | 5 | | 3 | 2 | 5 | 5 | 8 | | 5 | 3 | 8 | 8 | 13 | | 8 | 5 | 0 | 13 | 8 | +------+------+------+--------+-------------+生成初始斐波那契数列的一种方法是使用递归公共表表达式。有关示例,请参见 斐波那契数列生成。One way to generate the initial set of Fibonacci numbers is to use a recursive common table expression. For an example, see Fibonacci Series Generation.
你不能对这个函数的 rows 参数使用负值。You cannot use a negative value for the rows argument of this function.
LAST_VALUE([expr)null_treatment]over_clause返回窗口帧中最后一行的
expr的值。Returns the value ofexprfrom the last row of the window frame.over_clause的说明请参见 第 14.20.2 节,“窗口函数概念与语法”。null_treatment的说明请参见本节介绍部分。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.null_treatmentis as described in the section introduction.有关示例,请参见
FIRST_VALUE()函数描述。For an example, see theFIRST_VALUE()function description.LEAD([expr[,N[,default]])null_treatment]over_clause返回在其分区中领先(跟随)当前行
N行的行的expr的值。如果没有这样的行,返回值为default。例如,如果N为 3,则对于最后三行,返回值为default。如果N或default缺失,则默认值分别为 1 和NULL。Returns the value ofexprfrom the row that leads (follows) the current row byNrows within its partition. If there is no such row, the return value isdefault. For example, ifNis 3, the return value isdefaultfor the last three rows. IfNordefaultare missing, the defaults are 1 andNULL, respectively.N必须是字面上的非负整数。如果N为 0,则expr会对当前行进行评估。Nmust be a literal nonnegative integer. IfNis 0,expris evaluated for the current row.N不能为NULL,并且必须是以下任一形式中从0到263(含)范围内的整数:Ncannot beNULL, and must be an integer in the range0to263, inclusive, in any of the following forms:无符号整数常量字面值an unsigned integer constant literal
一个位置参数标记 (
?)a positional parameter marker (?)用户定义的变量a user-defined variable
存储过程中的局部变量a local variable in a stored routine
over_clause的说明请参见 第 14.20.2 节,“窗口函数概念与语法”。null_treatment的说明请参见本节介绍部分。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.null_treatmentis as described in the section introduction.有关示例,请参见
LAG()函数描述。For an example, see theLAG()function description.不允许在此函数的 rows 参数中使用负值。Use of a negative value for the rows argument of this function is not permitted.
NTH_VALUE([expr,N)from_first_last] [null_treatment]over_clause返回窗口帧中第
N行的expr的值。如果不存在这样的行,则返回值为NULL。Returns the value ofexprfrom theN-th row of the window frame. If there is no such row, the return value isNULL.N必须是一个正整数常量。Nmust be a literal positive integer.from_first_last是 SQL 标准的一部分,但 MySQL 实现只允许FROM FIRST(这也是默认值)。这意味着计算从窗口的第一行开始。FROM LAST会被解析,但会产生错误。要获得与FROM LAST相同的效果(计算从窗口的最后一行开始),请使用ORDER BY倒序排序。from_first_lastis part of the SQL standard, but the MySQL implementation permits onlyFROM FIRST(which is also the default). This means that calculations begin at the first row of the window.FROM LASTis parsed, but produces an error. To obtain the same effect asFROM LAST(begin calculations at the last row of the window), useORDER BYto sort in reverse order.over_clause的说明请参见 第 14.20.2 节,“窗口函数概念与语法”。null_treatment的说明请参见本节介绍部分。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.null_treatmentis as described in the section introduction.有关示例,请参见
FIRST_VALUE()函数描述。For an example, see theFIRST_VALUE()function description.此函数的行参数不能使用
NULL。You cannot useNULLfor the row argument of this function.NTILE(N)over_clause将一个分区划分为
N个组(桶),为分区中的每一行分配其桶号,并返回当前行在其分区中的桶号。例如,如果N是 4,NTILE()将行划分为四个桶。如果N是 100,NTILE()将行划分为 100 个桶。Divides a partition intoNgroups (buckets), assigns each row in the partition its bucket number, and returns the bucket number of the current row within its partition. For example, ifNis 4,NTILE()divides rows into four buckets. IfNis 100,NTILE()divides rows into 100 buckets.N必须是字面值的正整数。桶号的返回值范围从 1 到N。Nmust be a literal positive integer. Bucket number return values range from 1 toN.N不能为NULL,并且必须是以下任一形式中从0到263(含)范围内的整数:Ncannot beNULL, and must be an integer in the range0to263, inclusive, in any of the following forms:无符号整数常量字面值an unsigned integer constant literal
一个位置参数标记 (
?)a positional parameter marker (?)用户定义的变量a user-defined variable
存储过程中的局部变量a local variable in a stored routine
此函数应与
ORDER BY一起使用,以将分区行按所需顺序排序。This function should be used withORDER BYto sort partition rows into the desired order.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.以下查询显示了,对于
val列中的值集合,将行划分为两组或四组后得到的百分位数值。作为参考,该查询还使用ROW_NUMBER()显示行号:The following query shows, for the set of values in thevalcolumn, the percentile values resulting from dividing the rows into two or four groups. For reference, the query also displays row numbers usingROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',NTILE(2) OVER w AS 'ntile2',NTILE(4) OVER w AS 'ntile4'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+--------+--------+ | val | row_number | ntile2 | ntile4 | +------+------------+--------+--------+ | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 1 | 1 | | 3 | 4 | 1 | 2 | | 3 | 5 | 1 | 2 | | 3 | 6 | 2 | 3 | | 4 | 7 | 2 | 3 | | 4 | 8 | 2 | 4 | | 5 | 9 | 2 | 4 | +------+------------+--------+--------+不允许使用构造
NTILE(NULL)。The constructNTILE(NULL)is not permitted.PERCENT_RANK()over_clause返回当前行值以下的分区值百分比,不包括最大值。返回值范围从 0 到 1,表示行的相对排名,计算公式如下,其中
rank是行的排名,rows是分区中的行数:Returns the percentage of partition values less than the value in the current row, excluding the highest value. Return values range from 0 to 1 and represent the row relative rank, calculated as the result of this formula, whererankis the row rank androwsis the number of partition rows:(
rank- 1) / (rows- 1)该函数应与
ORDER BY一起使用,以将分区行排序为所需的顺序。如果没有ORDER BY,所有行都被认为是同行。This function should be used withORDER BYto sort partition rows into the desired order. WithoutORDER BY, all rows are peers.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.示例请参见
CUME_DIST()函数说明。For an example, see theCUME_DIST()function description.RANK()over_clause返回当前行在其分区内的排名,可能有间隔。具有相同值的行被视为并列,并获得相同的排名。如果存在大小大于一的分组,该函数不会为并列组分配连续的排名;结果是非连续的排名数字。Returns the rank of the current row within its partition, with gaps. Peers are considered ties and receive the same rank. This function does not assign consecutive ranks to peer groups if groups of size greater than one exist; the result is noncontiguous rank numbers.
该函数应与
ORDER BY一起使用,以将分区行排序为所需的顺序。如果没有ORDER BY,所有行都被认为是同行。This function should be used withORDER BYto sort partition rows into the desired order. WithoutORDER BY, all rows are peers.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.以下查询显示了
RANK()(会产生带间隙的排名)与DENSE_RANK()(会产生无间隙的排名)之间的差异。查询显示了val列中值集合中每个成员的排名值,该列包含一些重复值。RANK()会将相同的值(重复值)分配相同的排名,之后的更大值的排名会比同级值的数量少一名。DENSE_RANK()也会为相同的值分配相同的排名,但之后的更高值的排名只比前一个大一。为了参考,查询还使用ROW_NUMBER()显示了行号:The following query shows the difference betweenRANK(), which produces ranks with gaps, andDENSE_RANK(), which produces ranks without gaps. The query shows rank values for each member of a set of values in thevalcolumn, which contains some duplicates.RANK()assigns peers (the duplicates) the same rank value, and the next greater value has a rank higher by the number of peers minus one.DENSE_RANK()also assigns peers the same rank value, but the next higher value has a rank one greater. For reference, the query also displays row numbers usingROW_NUMBER():mysql>
SELECTval,ROW_NUMBER() OVER w AS 'row_number',RANK() OVER w AS 'rank',DENSE_RANK() OVER w AS 'dense_rank'FROM numbersWINDOW w AS (ORDER BY val);+------+------------+------+------------+ | val | row_number | rank | dense_rank | +------+------------+------+------------+ | 1 | 1 | 1 | 1 | | 1 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 3 | 6 | 4 | 3 | | 4 | 7 | 7 | 4 | | 4 | 8 | 7 | 4 | | 5 | 9 | 9 | 5 | +------+------------+------+------------+ROW_NUMBER()over_clause返回当前行在其分区内的行号。行号范围从 1 到分区中的行数。Returns the number of the current row within its partition. Rows numbers range from 1 to the number of partition rows.
ORDER BY会影响行编号的顺序。如果没有ORDER BY,行编号是非确定性的。ORDER BYaffects the order in which rows are numbered. WithoutORDER BY, row numbering is nondeterministic.ROW_NUMBER()会为同行分配不同的行号。要为同行分配相同的值,请使用RANK()或DENSE_RANK()。有关示例,请参阅RANK()函数说明。ROW_NUMBER()assigns peers different row numbers. To assign peers the same value, useRANK()orDENSE_RANK(). For an example, see theRANK()function description.over_clause如 第 14.20.2 节,“窗口函数概念和语法” 中所述。over_clauseis as described in Section 14.20.2, “Window Function Concepts and Syntax”.