在窗口中每条记录动态地应用聚合函数(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;

MySQL开窗聚合函数——SUM(),AVG(),MIN(),MAX()_聚合函数

根据上面的结果,可以明显的看出,sum()操作是对每一行进行迭代,迭代之前的总数,那么有的人就会疑问这个有什么用呢?

假设,你是公司的财务负责人,现在你需要统计一下每个部门的每月薪水消费是多少,那么每一次进入新的员工,就会加入新的员工薪水,这个时候我们可以按照每个月进行统计,统计各个部门的薪水需求是多少,一目了然的统计表格,会让老板给你升职加薪的!

如果没有order by 操作就会对所有的数据进行聚合操作

select  
dname,
ename,
salary,
sum(salary) over(partition by dname ) as '总数'
from employee;
-- 如果没有order by排序语句 默认把分组内的所有数据进行sum操作

MySQL开窗聚合函数——SUM(),AVG(),MIN(),MAX()_聚合函数_02

那么这样的操作可以做些什么,有时候我们可以这样的数据计算,该员工的薪水占比该部门的比率是多少,当我们灵活运用这种函数的时候,我们就会发现可以挖掘出很多的有效的信息。

当然我们也可以控制行数,开头和结尾

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;

MySQL开窗聚合函数——SUM(),AVG(),MIN(),MAX()_窗口函数_03

从当前行向上取出三个值,相加然后和当前行相加,就得到了当前行的最终值,如果是没有的话,那么就取到有的值。

select  
dname,
ename,
salary,
sum(salary) over(partition by dname order by hiredate rows between 3 preceding and 1 following) as c1
from employee;

MySQL开窗聚合函数——SUM(),AVG(),MIN(),MAX()_聚合函数_04

 这里就是取出前面三行和后面一行,再去和本身相加,最终得到最终值

select  
dname,
ename,
salary,
sum(salary) over(partition by dname order by hiredate rows between current row and unbounded following) as c1
from employee;

MySQL开窗聚合函数——SUM(),AVG(),MIN(),MAX()_聚合函数_05

 从当前行加到最后

当然,学会了这个语法结构和本质的原理之后,我们可以将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不要忘记了

每文一语

加油!