开窗函数 什么是开窗函数?开窗函数是在MySQL8。0以后才新加的功能,因此,要想直接使用开窗函数,则mysql版本要8。0以上。其实开窗函数是在满足某种条件的记录集合上执行的特殊函数。开窗函数的本质还是聚合运算,只不过它更具灵活性,它对数据的每一行,都使用与该行相关的行进行计算并返回计算结果。接下来,我们介绍开窗函数的相关语法;具体语法如下: 开窗函数名(〔字段名〕)over(〔partitionby分组字段〕〔orderby排序字段〔desc〕〕〔细分窗口〕) rowsbetweenxxxandxxx可出现的关键词:unbounded:无限的preceding:在之前following:在之后currentrow:当前行 over()中的关键字: 行数在前2行和后4行 over(orderbysalaryrowsbetween2precedingand4following) 下面三条语句等效(都是查所有数据): 行数前无限到后无限 over(orderbysalaryrowsbetweenunboundedprecedingandunboundedfollowing) over(orderbysalaryrangebetweenunboundedprecedingandunboundedfollowing) 等效 over(partitionbynull) rownumber()over(partitionbyorderby) rank()over(partitionbyorderby) denserank()over(partitionbyorderby) count()over(partitionbyorderby) max()over(partitionbyorderby) min()over(partitionbyorderby) sum()over(partitionbyorderby) avg()over(partitionbyorderby) firstvalue()over(partitionbyorderby) lastvalue()over(partitionbyorderby) lag()over(partitionbyorderby) lead()over(partitionbyorderby) 引入oracle数据库的Scott测试表数据 数据说明 1。emp员工表 2。dept部门表 3。salgrade工资等级表 查询所有员工的平均工资 selectavg(sal)fromemp; 使用开窗函数实现 select,avg(sal)over()fromemp; 从结果上看我们的窗口函数显示的是每一行,而普通的聚合函数则是只有一个结果 查询部门的平均工资 selectdeptno,avg(sal)avgsalfromempgroupbydeptno; 接下来使用开窗函数查询部门的平均工资 select,avg(sal)over(partitionbydeptno)avgsalfromemp; 既然开窗函数都可以通过我们的一般聚合函数实现,那么为什么还要有开窗函数呢?其实,我们在前下面的一个案例,就只能用开窗函数实现了,其它的函数不可以实现的; 查询员工工资,并显示第一行到最后一行的工资汇总 selectemp。,sum(sal)over(orderbysalrowsbetweenunboundedprecedingandunboundedfollowing)fromemp; 查询员工工资,并显示第一行到当前行的工资汇总 selectemp。,sum(sal)over(orderbysalrowsbetweenunboundedprecedingandcurrentrow)fromemp; 查询员工工资,并显示从当前行到最后一行的汇总 selectemp。,sum(sal)over(orderbysalrowsbetweencurrentrowandunboundedfollowing)fromemp; 查询员工工资,并显示从上一行到当前行的汇总 selecte。,sum(sal)over(orderbysalrowsbetween1precedingandcurrentrow)fromempe; 查询员工工资,并显示上一行和下一行的汇总 selectemp。,sum(SAL)over(orderbySALrowsbetween1precedingand1following)fromemp; 查询员工工资,按照部门分组并显示每个组的工资总和 selectemp。,sum(sal)over(partitionbyemp。deptnoorderbysalrowsbetweenunboundedprecedingandunboundedfollowing)fromemp; 查询员工工资,按照部门分组并显示每个组从第一行到当前行的工资总和 selectemp。,sum(sal)over(partitionbydeptnoorderbysalrowsbetweenunboundedprecedingandcurrentrow)fromemp; 普通的聚合函数用groupby分组,每个分组返回一个统计值。分析函数采用partitionby分组,并且每组每行都可以返回一个统计值。 firstvalue()与lastvalue() 取首尾记录值 selectemp。,lastvalue(sal)over(orderbysal)fromemp; selectemp。,firstvalue(sal)over(orderbysal)fromemp; selectemp。,lastvalue(sal)over(orderbysalrowsbetweenunboundedprecedingandunboundedfollowing)fromemp; rank(),denserank()与rownumber():求排序以下三个分析函数用于计算一个行在一组有序行中的排位序号从1开始ROWNUMBER返回连续的排序,不论值是否相等DENSERANK具有相等值的行排序相同,序号是连续的RANK具有相等值的行排序相同,序数随后跳跃 selectemp。,rownumber()over(orderbysaldesc)fromemp; selectemp。,rank()over(orderbysal)fromemp; selectemp。,denserank()over(orderbysal)fromemp; lag()允许您回顾多行并从当前行访问行的数据 lead()从同一结果集中的当前行访问后续行的数据。 selectemp。,lag(SAL,1)over(orderbysal)fromemp; selectemp。,lead(SAL,1)over(orderbysal)fromemp;