mysql分组后组内排序_数据小白的转行之路-MYSQL(七)
目录
一、 什么是窗口函数?
1. 什么是窗口函数
窗口函数,可以对数据库数据进行实时分析处理。
基本语法如下:
<窗口函数> over by (partition by <要分组的列名>
order by <要排序的列名>)
2. 窗口函数有什么用?
窗口函数可以解决以下几类常见的问题:
a) 排名问题:每个班按照总成绩来排名
b) TopN问题:找出每个班成绩前三名的同学
二、 如何使用窗口函数
1. 以rank()专用窗口函数为例:
原数据如下:
如果我们想在每个班级内按成绩排名,得到以下的效果:
则我们用rank()专用窗口函数实现的语句如下:
select * , rank() over (partition by 班级 order by 成绩 as desc) as Ranking
from 班级表;
现在我们一步一步来拆解:
首先,我们要先按班级分组,找到每个班级都有哪些学生,对应哪些成绩(partition by 班级)
然后,再在各个班级内按成绩倒序排列,从而让成绩由高到低排列(order by 成绩 desc)。
通过下图,可以理解partition by 和 order by 的顺序和作用。
2. group by和 窗口函数的区别
group by 分组汇总后改变了表的行数,一行只有一个类别。这也是为什么group by后通常要和having 加聚合函数一起使用,以表示一个值而不是一组数据。
窗口函数它不会减少原表中的行数。如:
三、 怎么用?
1. 专用窗口函数
a) 区别:
A、 不考虑相同数值并列情况:row_number()
B、 考虑相同数值并列情况:rank() 和 dense_rank()
例子:
找课程号为‘0003’的成绩,并且分别用这三种专用窗口函数排序。
从上述例子可知,在不考虑数值相同并列的情况下,用row_number()排序的结果是1,2,3,4,相当于给各个成绩所在的行添加行数。
而rank()和dense_rank()都考虑了数值相同的并列情况,但是rank()的并列名次行会占用下一名次的位置,而dense_rank则不会占用。
我们可以用下图记忆,方便理解:
b) 面试经典案例:
A、 经典的排名问题:找课程号为‘0003’的成绩,并且按成绩高低排名
两个相同的分数,排名应该是一样的。而相同分数后的下一个名次,应该是下一个连续的整数值。也就是说,名次之间是连续的,不应该有间隔。
根据这个例子,我们可以确定使用dense_rank():
B、 经典的TopN问题:求各科成绩的最高分
方法一:关联子查询
方法二:窗口函数
TopN问题模版:
Select *
From (select*, row_number()(无重复值)或者 dense_rank()(有重复值) over (patrtition by <要分组的列名> order by <要排序的列名>) as Ranking from 表名) as a
Where Ranking <= N
2. 聚合函数作窗口函数
a) 作用:
从上图可得,所有聚合函数的结果都是当前行在各分组内自身与前面结果的累计。因此聚合函数作为窗口函数,可以在每一行的数据中直观的看到截止到本行数据,该组统计数据的情况(最大值、最小值、总计等)。
b) 经典面试题:求各科大于平均成绩的学生
3. 窗口函数的移动平均
和聚合函数作窗口函数中的avg()求平均值类似,只不过移动平均的平均值添加了一个范围。
例子:求课程号为0003的移动平均值
学号0001的移动平均值为99/1=99
学号0002的移动平均值为(99+80)/2=89.5
学号0003的移动平均值为(99+80+80)/3=86.3
学号0004的移动平均值为(80+80+60)/3=73.3
每一行移动平均值的结果,都是当前行和前两行的平均(共3行)。而想要计算当前行与前n行的平均时(共n+1行),则修改一下rows……preceding中间的数值即可。
四、 注意事项
1. 专用窗口函数的括号不能漏掉
2. 原则上窗口函数只能写在select子句中
3. Partition by 可以省略,结果就不分组了
五、 总结
1. 窗口函数语法:
<窗口函数> over (partition by <要分组的列名> order by <要排序的列名>) as……
From 表名
窗口函数包含两大类,专用窗口函数和聚合函数
2. 窗口函数具有以下功能
a) 分组和排序
b) 分组后不减少原表的行数,经常用于组内排名
3. 经典面试问题:
a) 经典排名问题
b) 经典TopN问题
c) 每个组里比较的问题
mysql分组后组内排序_数据小白的转行之路-MYSQL(七)相关推荐
- mysql分组后组内排序_图解排序 3/10 希尔排序
希尔排序,它是由 D.L.Shell 于1959 年提出而得名.根据它的名字很难想象算法的核心思想.[ 所以只能死记硬背了,面试官问:希尔排序的思想是什么?].它的核心思想是把一个序列分组,对分组后的 ...
- Mysql 分组后组内排序按字段取最大或最小的数据
我的个人博客:逐步前行STEP 示例: 1.将文章按类型的分组,并获取类型分组中最新的一篇文章 select author,max(`updated_at`) as updated_at from a ...
- mysql分组后组内排名_SQL实现group by 分组后组内排序
在一个月黑风高的夜晚,自己无聊学习的SQL的时候,练习,突发奇想的想实现一个功能查询,一张成绩表有如下字段,班级ID,英语成绩,数据成绩,语文成绩如下图 实现 查询出 每个班级英语成绩最高的前两名的记 ...
- stream list 分组后组内排序
最近开发遇到了一个需求,需要对list按某个字段分组,分组后需要对组内的list按某个字段排序,经过各种探索有了下边的解决方法,不知道有没有更好的方法package com.sensedeal.ind ...
- mysql 排名_SQL语句mysql排名、分组后组内排名、取各组的前几名
数据: 一.整体排名(3种) -- 普通排名:从1开始,顺序往下排 set @rank =0;select city , score, @rank := @rank+1 rank from cs or ...
- mysql分组取最新时间的数据
mysql分组后显示最新数据 方法一:NOT EXISTS SELECT e.GROUP_COLUMN, e.COMPARE_TIME FROM ...
- 关于oracle分组后组外排序的问题
[求助]关于oracle分组后组外排序的问题 只用查询语句实现: DEPTNO ENAME SAL TOP3 ---------- ---------- ...
- Lambda表达式 Linq SQL Server 分组后获取第一条数据或最小(最大)数据
1.Lambda表达式 以下是从网上粘贴下来 经测试失败 提示方法"First"只能用作最终查询操作.请考虑在这个实例中使用方法"FirstOrDefault" ...
- Tez union all时,识别不到subdir,count(*)=0,以及分组,组内排序错误。
背景:Tez union all时,识别不到subdir,count(*)=0 现象1:分组,组内排序错误,不同引擎执行结果不同. 现象2:select
最新文章
- Tengine AIFramework框架
- 134人!国家重点研发计划“生物大分子与微生物组”重点专项会评专家名单
- etcd分布式之负载均衡
- [转] 程序员面试题精选100题(35)-找出两个链表的第一个公共结点
- http 状态码 504 502
- 文档过期打不开怎么办_标准的产品需求文档在这里!(详细说明版)(2)
- 嵌入式操作系统_航天科工海鹰翼辉嵌入式操作系统获自主原创“身份证”
- Olympic Games -basketball
- 柳氏管理学:感恩是双向的,强调单方面都是别有用心
- multisim虚拟电子实验室安装包及汉化包(百度网盘地址)
- 规划计算机网络需要考虑,论计算机网络规划及实现
- R语言绘制Cleverland点图
- python面面观单元测试_第2周 python面面观
- anaconda使用和入门
- 杭州住房公积金提取说明
- tc275的flexcan的接收与发送
- Google 主页空间测试报告
- 专访新致云田奎:行业云服务的差异化发展 初创公司上云迫在眉睫
- 高仿 QQ影音播放器 皮肤
- Python 制作、发布与安装模块