sql分组后组内排序_SQL的开窗函数|解决topN、组内排序、移动平均问题

一、开窗函数(OLAP函数)

1、定义

用于为行定义一个窗口(这里的窗口是指运算将要操作的行的集合、一组记录,而不是普通意义上的窗户),它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行的列和聚合列。

开窗函数分为排序开窗函数和聚合开窗函数。

2、基本语法

<排序函数/聚合函数> over (partition by <用于分组的列名> order by <用于排序的列名>)

排序函数:rank(),dense_rank(),row_number()

聚合函数:sum(),avg(),count(),max(),min()

3、功能

(1)进行排序、生成序号

(2)返回多列值。

二、排序开窗函数

1、三种排序开窗函数的区别

be35e2dd978111fceddb65375ea6e36c.png

25be321ac69cd32fb267d278c70852de.png
让班级表里的各班按成绩进行排名

注意:使用排序函数时,括号里没有参数

2、解决topN问题:子查询+排序开窗函数

76c5171374f8a114c6423432f8b8cd78.png
从各科成绩表中查询每个学生成绩最高的两科目
select * from 
(select *, dense_rank() over(partition by 分组列 order by 排名列 desc)as 排名
from 各科成绩表) as a
where 排名<=N;

注意:这里子查询产生的新表必须命名,否则报错。

213c685c31372987768dafbb4438138d.png

三、聚合开窗函数

1、聚合开窗函数和聚合函数的区别

7b609fc1e42b2d6b44023a4ed9977467.png

可以说,聚合开窗函数是加强版的聚合函数。

下面举个例子,要求在各科成绩表中增加一列,按学生对成绩求累和(自身和前几行的求和)

59c6063c49abf6510af0cbdea7223f2c.png
前三项数值错误

这里可以看到,猴子的成绩累和列出现错误,这是为什么呢?

问题出现在“order by 成绩”处。
因为order by将成绩相等的项归为了一类,那么在排序时就无所谓谁前谁后,它们都是同一行的,所以猴子的累和列,前三项都是90+90+90=270。

解决方法是添加排序条件,使每个成绩都可以被唯一识别,不再归为同一类。
改为“order by 科目,成绩“

78c0b0d9a744a2e9d449f9840790e457.png
结果正确

2、解决组内比较(平均值、最大值、最小值)

d2d1ec9e5ca630ac20736a2827cdd868.png
查询单科成绩高于该科目平均成绩的学生名单

3、解决移动平均问题(观察相邻名次的平均成绩)

537c30b30667b163bf047278bea50e0d.png
按科目求各科移动两项的平均成绩

小结

本章学习内容解决的三个业务问题

topN问题:排序开窗函数+子查询

组内比较问题:聚合开窗函数+子查询,也可以用关联子查询做

移动平均问题:聚合开窗函数

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值