玛雅人造不出轮子,也不需要轮子.
在学完基础以后,通过子查询和聚合函数,理论上可以解决任何复杂的sql查询问题,但是人类发明出来轮子绝对不是用来看着它转圈的.
窗口函数和聚合函数非常相似,区别在于聚合函数是将多个行结合成一个结果,而窗口函数是以某个区域(窗口)为界限,进行计算,不会导致合并.
举个例子,我们有三个人,分别为80 90 100三个成绩
如果我们使用聚合函数avg,那么最终输出的元组只有一条,也就是90
但是如果我们把聚合函数avg改造成窗口函数avg() over(),那么三条数据不会改变,窗口函数会分别计算出90来
这就是窗口函数的作用
窗口其实肥肠类似我们在聚类查询的时候操作group by ,group by事情多而且有些数据库要求特别严格 , 窗口相当于以某一行为锚点,来构建窗口.
窗口的构建,其实就是后面的那个over语句
function() over(partition by ?? order by ?? {RANGE|ROWS})
其中逐个解析里面的参数(注意一下这几个参数之间不能用,链接,并列即可)
partition by: 类似group by的作用,按照某个值进行划分,划分出第一个窗口,举个例子
数据库如下
我们执行这个语句
select * ,sum(salry) over(partition by name) as rank_salary from test;
查询出来的结果就是
这就是partition by的作用,其实就是第一步分出窗口
order by : 这个东西很眼熟,我们在聚合函数里也用过,其实功能也是一样的,根据某个东西来进行排序,支持asc和desc两种顺序.同时,这个东西也是rank等和顺序有关函数的前提
但是有一个小小的问题,就是order by会改变默认分区,一旦使用了order by,RANGE属性就会被改成(从当前行到该窗口的第一行),也就是between unbounded preceding and current row
下面是例子,执行代码
select * ,sum(salary) over(partition by name order by salary) as rank_salary from test;
RANGE|ROWS: 对于不听话的order by 我们给出的惩罚是.......
在原本的partition的基础上,进一步进行切割,指定具体的窗口大小
其中一共有五个关键字可以作为范围
UNBOUNDED PRECEDING:表示窗口帧没有上限,从窗口的起始位置开始计算,包括窗口的第一行。
N PRECEDING:表示窗口帧的上限是距离当前行 N 行之前的行,包括第 N 行。N 必须是一个非负整数。
CURRENT ROW:表示窗口帧的上限是当前行。
N FOLLOWING:表示窗口帧的下限是距离当前行 N 行之后的行,包括第 N 行。N 必须是一个非负整数。
UNBOUNDED FOLLOWING:表示窗口帧没有下限,直到窗口的结束位置,包括窗口的最后一行。
使用效果,比如我们想要把窗口指定为前一个和后一个,加上本身
select * ,sum(salary) over(order by salary RANGE between
1 preceding and 1 following) as rank_salary from test;
窗口的概念已经介绍完了,接下来就了解一下其他的窗口函数即可
等待补充