解决数据排名问题——mysql中的窗口函数

对于SQL语句的使用,我们知道怎样使用它的增删改查,但是如果遇到这样的查询需求时,怎样得到各部门工资排名前N名员工列表,环比如何计算,查找各部门每人工资占部门工资的百分比。对于这写类型的查询需求,传统的查询语句解决起来非常的繁琐,但要解决此类问题,最方面的就是使用窗口函数。

             

 

窗口函数的定义

        什么是窗口函数,窗口的概念十分重要,可以理解为记录集合,窗口函数也就是满足某种条件的记录集合上执行的特殊函数,对于每条记录都要在此窗口内执行函数,有的函数,随着记录不同,窗口大小都是固定的,这种属于静态窗口,有的函数则相反,不同的记录对应着不同的函数。窗口函数也叫OLAP函数,可以对数据库数据进行实时分析处理

        窗口函数和聚合函数有所不同,聚合函数时将多个记录聚合在一起,而窗口函数时每条记录都会执行,有几条记录执行完还是几条

按照功能划分,可以将窗口函数分为下面5种类型

  • 序号函数:row_number()/rank()/dense_rank()

  • 分布函数:percent_rank()/cume_dist()

  • 前后函数:lag()/lead()

  • 头尾函数:first_val()/last_val()

  • 其他函数:nth_value()/nfile()

1、窗口函数的使用

# 窗口函数语法<窗口函数> over (partition by <要分组的列名> order By <要排序的列名>)

1、窗口函数。这里主要介绍两种常见的窗口函数,(1)专用函数(row_number()、rank()、dense_rank())(2)聚合函数作为窗口函数使用(sum()、avg())

2、partition by 子句:窗口按照那些字段进行分组,窗口函数在不同的分组上分别执行,可以省略

3、原则上窗口函数只能写在select 子句中,不用在where和group by子句中使用、

4、order by 子句中可以通过desc、asc指定降序或者升序,如果省略,默认会按照升序asc进行排序

示例1:按照每个班级进行排名select *,rank() over(partition by 班级 over By 成绩 desc)as 排名from table1

结果展示:

学号班级成绩排名
0011901
0021802
0031703
0042901
0052802
示例2:函数之间的对比展示select *,rank() over (order by 成绩 desc)as 排名1,          dense_rank() over(order by 成绩 desc)as 排名2,          row_number() over(order by 成绩 desc)as 排名3from table1;
学号班级成绩排名1排名2排名3
001198111
002397222
003296333
004195444
005195445
006390656

解释:

rank()函数:计算排序时,如果有相同位次的记录,会占用下一名次的位置

dense_rank()函数:计算排序时,如果有相同位次的记录,不占用下一名次位置

row_number函数:计算排序时,不会出现相同位次的记录,是连续的位次

示例3:使用聚合函数作为窗口函数select *,sum(成绩) over (order by 学号)as 总和,          avg(成绩) over (order by 学号)as 平均值,          count(成绩) over (order by 学号)as 计数,          min(成绩) over (order by 学号)as 最小值from 班级表​​​​​​​

2、常见窗口函数案例

1、排名问题​​​​​​​

示例:排名函数之间的对比展示select *,rank() over (order by 成绩 desc)as 排名1,          dense_rank() over(order by 成绩 desc)as 排名2,          row_number() over(order by 成绩 desc)as 排名3from table1;
学号班级成绩排名1排名2排名3
001198111
002397222
003296333
004195444
005195445
006390656

2、topN问题​​​​​​​

示例:找出每组最大的N条记录select * from (select * ,row_number() over (partition by 课程号1order by 成绩 desc)as 排名 from table)as a where 排名<=2;
学号课程号成绩排名
0011981
0021972
0032871
0042802
0053601

3、每组之间进行比较​​​​​​​

示例:每组之间的比较(查找单科成绩高于该科目平均成绩的名单)select * from (select *,avg(成绩) over (partition by 科目)as 各科平均成绩 from table)as awhere a.成绩>a.各科平均成绩
学号科目成绩各科平均成绩
001科19089
002科29890
003科37876
004科48967

随着大数据的时代的到来,数据变得越来越重要,数据可以帮助我们来看清行业的本质,也可以帮助我们更加快速的了解一个行业,关注公众号——有趣的数据,走进数据的时代。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值