MySQL——窗口函数

语法

函数名称([字段名]) 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()函数

参数:

  1. 表达式或字段
  2. 偏移量
  3. 控制赋值,默认为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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/cold___play/article/details/120598187