语法
函数名称([字段名]) OVER([PARTITION BY <分组字段>][ORDER BY <排序字段> [DESC]] [<FRAME字句>])
- PARTITION BY字句:按照指定字段进行分区,两个分区由边界分割,即所谓的"窗口"。如果没有指定,那么它把整个结果集作为一个分组。窗口函数在不同的分区内分别执行,在跨越分区边界时重新初始化。
- ORDER BY子句:按照指定字段进行排序,开窗函数将按照排序后的记录顺序进行编号。可以和PARTITION BY子句配合使用,也可以单独使用。默认为升序排列。
- FRAME子句:当前分区的一个子集,用来定义子集的规则,通常用来作为滑动窗口使用。
- ROWS语法:
- ROWS BETWEEN (
expr 为指定数值) UNBOUNDED PRECEDING边界是分区中的第一行 / N PRECEDING边界是当前行减去expr的值 / expr FOLLOWING边界是当前行加上expr的值 / CURRENT ROW边界是当前行 AND UNBOUNDED FOLLOWING边界是分区中的最后一行 / expr PRECEDING / expr FOLLOWING / CURRENT ROW - ROWS UNBOUNDED PRECEDING / expr PRECEDING / expr FOLLOWING / CURRENT ROW
- 默认:ROWS BETWEEN UNBOUNDED PRECENDING AND CURRENT ROW
分类
按照函数功能不同,MySQL支持的窗口函数分为如下几类:
- 序号函数
- row_number()连续的序号(不管有没有重复,1.2.3.4.5.6)
- rank()连续间断的序号(重复给相同序号,后面会跳过重复的序号,1.2.3.3.3.6.7)
- dense_rank()连续不断的序号(重复的会给相同的序号,1.2.3.3.3.4.5)
- 分布函数:percent_rank() / cume_dist()
- 前后函数:lag() / lead()
- 头尾函数:first_value() / last_value()
- 其他函数:nth_value() / nfile()
名称 | 描述 |
---|
CUME_DIST() | 计算一组值中的一个值的累计分布 | DENSE_RANK() | 根据ORDER BY子句分区中的每一行分配一个等级。它将相同的等级分配给具有等同值的行。如果两行或更多行具有相同的排名,则排名值序列中将没有间隔 | FIRST_VALUE() | 返回相对于窗口框架第一行指定表达式的值 | LAG() | 返回分区中当前行之前的第N行的值。如果不存在前一行,则返回NULL | LAST_VALUE() | 返回相对于窗口框架最后一行指定表达式的值 | LEAD() | 返回分区中当前行之后的第N行的值。如果不存在后续行,则返回NULL | NTH_VALUE() | 从从窗口框架的第N行返回参数值 | NTILE() | 将每个窗口分区的行分配到指定数量的排名中 | PERCENT_RANK() | 计算分区或结果中行的百分数等级 | RANK() | 与DENSE_RANK()函数相似,不同指出在于当两行或更多行具有相同等级时,等级值序列中存在间隔 | ROW_NUMBER() | 为分区中的每一行分配一个顺序整数 |
窗口函数与普通聚合函数的区别
- 聚合函数是讲多条记录聚合为一条;而窗口函数是每条记录都会执行,有几条记录执行完还是几条。
- SQL标准中允许所有聚合函数作为窗口函数。聚合函数作为窗口函数,可以在每一行的数据里直观的看到,截止到本行数据,统计数据是多少(最大值、最小值等)。同时可以看出每一行数据,对整体统计数据的影响。
示例
1. 根据省份分区求各市gdp并排序
SELECT
prov_name,
city_name,
gdp,
ROW_NUMBER ( ) OVER ( PARTITION BY prov_name ORDER BY gdp ) AS ranking
FROM
test_windows
SELECT
prov_name,
city_name,
gdp,
RANK ( ) OVER ( PARTITION BY prov_name ORDER BY gdp ) AS ranking
FROM
test_windows
SELECT
prov_name,
city_name,
gdp,
DENSE_RANK ( ) OVER ( PARTITION BY prov_name ORDER BY gdp ) AS ranking
FROM
test_windows
2. 根据省份分区统计各市gdp并累计求和
SELECT
prov_name,
city_name,
gdp,
SUM( gdp ) over ( PARTITION BY prov_name ORDER BY gdp ) AS 'ranking'
FROM
test_windows
3. lag()和lead()函数
参数:
- 表达式或字段
- 偏移量
- 控制赋值,默认为NULL
SELECT
prov_name,
city_name,
gdp,
lag ( gdp, 1 , '无') over ( PARTITION BY prov_name ORDER BY gdp ) AS 'ranking'
FROM
test_windows
SELECT
prov_name,
city_name,
gdp,
lead ( gdp, 1, '无') over ( PARTITION BY prov_name ORDER BY gdp ) AS 'ranking'
FROM
test_windows
|