本文介绍SQL窗口函数,读完后你将会:
- 能够使用窗口函数语句
- 了解窗口函数的存在目的,在需要的时候想到它
- 知道三种不同目的窗口函数的存在
窗口函数能做什么?
窗口函数对表格中的一组“行”进行操作,并为每个行返回一个值。所谓“窗口“指的是函数计算某一行相应值时考虑的其他”行"的集合。窗口函数使用“窗口行”中的值来计算返回的值。
、
窗口函数语句示例
对于下面这个表格(stu_info.class_table):
我们使用窗口函数语句:
得到下面表格:
我们来解释下这个语句。其中rank()是排序的“窗口函数”。其计算时的具体要求是“每个class内按score排名”,然后再对学生进行排序。窗口函数实现的具体细节,或者说是这个例子里面窗口的定义是靠后面紧跟的 over() 语句实现。细致地来看over()内这句话可以分为两部分:
- 按class分组
使用关键词partition by 实现 - 按score排名
使用 order by 实现。默认是按照升序(asc)排列。在本例中加了desc关键词表示降序排列。
over()语句内,partitionby 是可选的,而 order by 是必须有的。
看一下窗口是具体怎么定义出来的
通过上面语句over()中,partition by & order by 两组关键词,我们具体看下对表格发生了什么变化:
- 所有行按照 class 分成三组
- 每组内按照分数从高到低排名
我们在之前提到过
所谓“窗口“指的是函数计算某一行相应值时考虑的其他”行"的集合。窗口函数使用“窗口行”中的值来计算返回的值。
通过 over(partition by…, order by…) 将原始表格整理成上面形式后,我们在使用窗口函数rank()计算某一行相应值时,所考虑的“窗口”行就可以直接找到了。具体规则如下:
- 某一行对应的窗口行,在与此行数据共属同一组(指 partition by 区分开来的组别)
- 某一行对应的窗口行,是在同一组内,比此行排名靠前的所有行的集合(其中排名由 over() 中的 order by 决定)
我们来看下图示例:
窗口函数清单
SQL窗口函数可以分成下面三类
- 值返回
- FIRST_VALUE()
- LAG()
- LAST_VALUE()
- LEAD()
- 聚合
- AVG()
- COUNT()
- MAX()
- MIN()
- SUM()
- 排名
- CUME_DIST()
- DENSE_RANK()
- NTILE()
- PERCENT_RANK()
- RANK()
- ROW_NUMBER()
窗口函数语句中 partition by 与 group by 的区别
简而言之,partition by 出现在窗口函数后 over() 语句里,目标是通过给表格的行分组,最终帮助计算出窗口函数的结果。窗口函数紧跟在 select 后,实际上计算了一个新的列。计算结果不改变表格行数。 而 group by 在 SQL 中的目标是分组,然后进行总结计算。分组总结后,新表格的行数会减少,其数目和“组别”的个数一样。 所以说 partition by 是为了服务窗口函数创建新的列,group by 是为了将表格分组然后进行每组的统计总结计算。