在窗口中每条记录动态地应用聚合函数(SUM()、AVG()、MAX()、MIN()、COUNT()),可以动态计算在指定的窗口内的各种聚合函数值。
有的小伙伴可能会有所疑问,这和传统的聚合函数到底有什么区别呢?
其实最大的区别在于,一个操作列,一个是依次操作行,最终显示出每一行,最后的效果就是呈现叠加的效果,举一个简单的例子:
假如,小王每个月的薪水是不定的,第一个月是10000,第二个月是15000,第三个月是20000,第四个月是22000……,那么如果是sum()最终出现的结果就是叠加每个月的数值;但是如果使用sum() over(partition by XXX order by desc)
这里依然使用上一篇的文章的数据集
select dname, ename, salary, sum(salary) over(partition by dname order by hiredate) as pv1 from employee;
根据上面的结果,可以明显的看出,sum()操作是对每一行进行迭代,迭代之前的总数,那么有的人就会疑问这个有什么用呢?
假设,你是公司的财务负责人,现在你需要统计一下每个部门的每月薪水消费是多少,那么每一次进入新的员工,就会加入新的员工薪水,这个时候我们可以按照每个月进行统计,统计各个部门的薪水需求是多少,一目了然的统计表格,会让老板给你升职加薪的!
如果没有order by 操作就会对所有的数据进行聚合操作
select dname, ename, salary, sum(salary) over(partition by dname ) as '总数' from employee; -- 如果没有order by排序语句 默认把分组内的所有数据进行sum操作
那么这样的操作可以做些什么,有时候我们可以这样的数据计算,该员工的薪水占比该部门的比率是多少,当我们灵活运用这种函数的时候,我们就会发现可以挖掘出很多的有效的信息。
当然我们也可以控制行数,开头和结尾
rows between unbounded(开头) preceding and current(当前行) row
默认就是这样
select dname, ename, salary, sum(salary) over(partition by dname order by hiredate rows between 3 preceding and current row) as c1 from employee;
从当前行向上取出三个值,相加然后和当前行相加,就得到了当前行的最终值,如果是没有的话,那么就取到有的值。
select dname, ename, salary, sum(salary) over(partition by dname order by hiredate rows between 3 preceding and 1 following) as c1 from employee;
这里就是取出前面三行和后面一行,再去和本身相加,最终得到最终值
select dname, ename, salary, sum(salary) over(partition by dname order by hiredate rows between current row and unbounded following) as c1 from employee;
从当前行加到最后
当然,学会了这个语法结构和本质的原理之后,我们可以将sum换成avg或者max等聚合函数,最终的原理都是一样的。
俗话说:“学而不思则罔,思而不学则殆”,学习之后也需要自己去总结,不能盲目的学习,最终什么也没有收获到,这样的学习是低效率的学习。
语法结构需要熟记:rows between unbounded(开头) preceding and current(当前行) row
而且这一行代码是紧跟到order by 后面的,也就是说,按照这样的形式我们可以最终获取
rows是不需要变动的参数,between 也是不需要变动的参数
unbounded preceding :开头
number preceding :加上具体的数字就是往上取到多少值
注意:如果是数值的话,或者开头一定要跟上preceding这个参数
current row:表示当前行,如果出现这个那么也就是范围指定到后面了
其次不变的就是and
如果and后面跟上具体的数字,那么就是代表着向后取多少行
unbounded following:取到最后一行
number following:向后取到具体的行
注意:如果是数值和unbounded就需要注意加following
current row:表示当前行,如果出现这个那么也就是范围指定到后面了,注意row不要忘记了