目录

表结构

题目一:获取每个科目下前五成绩排名(允许并列)

分析:

题目二:获取每个科目下最后两名学生的成绩平均值

分析:

题目三:获取每个科目下前五成绩排名(不允许并列)

分析:

ROW_NUMBER()函数版

参考资料:


表结构

学生表如下:

CREATE TABLE `t_student` (`id` int NOT NULL AUTO_INCREMENT,`t_id` int DEFAULT NULL COMMENT '学科id',`score` int DEFAULT NULL COMMENT '分数',PRIMARY KEY (`id`)
);

数据如下:

题目一:获取每个科目下前五成绩排名(允许并列)

允许并列情况可能存在如4、5名成绩并列情况,会导致取前4名得出5条数据,取前5名也是5条数据。

SELECTs1.*
FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score < s2.score
GROUP BYs1.id
HAVINGCOUNT( s2.id ) < 5
ORDER BYs1.t_id,s1.score DESC

ps:取前4名时

分析:

1.自身左外连接,得到所有的左边值小于右边值的集合。以t_id=1时举例,24有5个成绩大于他的(74、64、54、44、34),是第6名,34只有4个成绩大于他的,是第5名......74没有大于他的,是第一名。

SELECT*
FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score < s2.score 

2. 把总结的规律转换成SQL表示出来,就是group by 每个student 的 id(s1.id),Having统计这个id下面有多少个比他大的值(s2.id)

SELECTs1.*
FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score < s2.score
GROUP BYs1.id
HAVINGCOUNT( s2.id ) < 5 

3. 最后根据 t_id 分类,score 倒序排序即可。

题目二:获取每个科目下最后两名学生的成绩平均值

取最后两名成绩

SELECTs1.*
FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.score
GROUP BYs1.id
HAVINGCOUNT( s1.id )< 2
ORDER BYs1.t_id,s1.score

并列存在情况下可能导致筛选出的同一t_id 下结果条数大于2条,但题目要求是取最后两名的平均值,多条平均后还是本身,故不必再对其处理,可以满足题目要求。

分组求平均值:

SELECTt_id,AVG(score)
FROM(SELECTs1.*FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.scoreGROUP BYs1.id HAVINGCOUNT( s1.id )< 2 ORDER BYs1.t_id,s1.score ) tt
GROUP BYt_id

结果:

分析:

1. 查询出所有t1.score>t2.score 的记录

SELECTs1.*,s2.*FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.score

2. group by s.id 去重,having 计数取2条

3. group by t_id 分别取各自学科的然后avg取均值

题目三:获取每个科目下前五成绩排名(不允许并列)

SELECT*
FROM(SELECTs1.*,@rownum := @rownum + 1 AS num_tmp,@incrnum :=CASEWHEN @rowtotal = s1.score THEN@incrnum WHEN @rowtotal := s1.score THEN@rownum END AS rownum FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.score,( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it GROUP BYs1.id ORDER BYs1.t_id,s1.score DESC ) tt
GROUP BYt_id,score,rownum
HAVINGCOUNT( rownum )< 5

分析:

1.引入辅助参数

SELECTs1.*,@rownum := @rownum + 1 AS num_tmp,@incrnum :=
CASEWHEN @rowtotal = s1.score THEN@incrnum WHEN @rowtotal := s1.score THEN@rownum END AS rownum
FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.score,( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it

2.去除重复s1.id,分组排序

SELECTs1.*,@rownum := @rownum + 1 AS num_tmp,@incrnum :=CASEWHEN @rowtotal = s1.score THEN@incrnum WHEN @rowtotal := s1.score THEN@rownum END AS rownum FROMstudent s1LEFT JOIN student s2 ON s1.t_id = s2.t_id AND s1.score > s2.score,( SELECT @rownum := 0, @rowtotal := NULL, @incrnum := 0 ) AS it GROUP BYs1.id ORDER BYs1.t_id,s1.score DESC 

3.GROUP BY    t_id, score, rownum   然后 HAVING 取前5条不重复的

ROW_NUMBER()函数版

必要条件:MySQL版本 8.0+

row_number() OVER ([PARTITION BY COL1] ORDER BY COL2)

表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)。

select * from (SELECT*,ROW_NUMBER() OVER(PARTITION BY t_id ORDER BY score DESC) top
FROMstudent
)t where top<=5

参考资料:

Mysql - 获取每个分类下面前几条数据

mysql mysql SELECT 自增数显示

mysql 每个分类前十名_一文解决所有MySQL分类排名问题

mysql:名次排名 (并列与不并列)

查询每个班成绩排名前三的学生信息

mysql mysql SELECT 自增数显示

MySQL 实现分组 TopN 问题

MySQL 分类排名(并列、不并列),分组TOP N,ROW_NUMBER()函数相关推荐

  1. mysql 每个分类前十名_一文解决所有MySQL分类排名问题

    导读 对数据库中的记录依据某个字段进行排序是一种常见需求,虽然简单的Order by可以胜任,但如果想要输出具体的排名却难以直接实现.如果再考虑重复排名或者分类排名,那么情况就更为复杂. 本文介绍4种 ...

  2. mysql怎么查询排第几名并列_MySQL并列排名和顺序排名查询

    准备.创建一张叫scores的表,内容如下.因为测试排名,所以就用最简单的结构.idscore199 280 387 460 580 699 需求.获取分数排名,要求并列排名.如果两个分数相同,则两个 ...

  3. mysql怎么做排名并列_MySQL实现排名并查询指定用户排名功能,并列排名功能

    MySQL实现排名并查询指定用户排名功能,并列排名功能 表结构: CREATE TABLE test.testsort ( id int(11) NOT NULL AUTO_INCREMENT, ui ...

  4. mysql并列查询_MYSQL实现排名及查询指定用户排名功能(并列排名功能)实例代码...

    前言 本文主要介绍了关于mysql实现排名及查询指定用户排名功能(并列排名功能)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 表结构: create table test ...

  5. mysql作排名,MYSQL实现排名及查询指定用户排名功能(并列排名功能)实例代码...

    前言 本文主要介绍了关于MYSQL实现排名及查询指定用户排名功能(并列排名功能)的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 表结构: CREATE TABLE test ...

  6. MySQL 实现排名(分组排名)

    在MYSQL的最新版本MYSQL8已经支持了排名函数RANK,DENSE_RANK和ROW_NUMBER.但是在5.*版本中还不支持这些函数,只能自己实现.实现方法主要用到了条件判断语句(CASE W ...

  7. MySQL实现排名、分组筛选、TopN问题

    之前在学习SQL时刷过一遍LeetCode上的SQL题,不过只做一遍效果并不是很好,很快也忘记了具体的解题思路.在这里将对其中的:Q176(第二高薪水) . Q177(第N高薪水) . Q178(分数 ...

  8. n个人排名,允许并列名次,共有多少种排名结果?

    n个人排名,允许并列名次,共有多少种排名结果? 经典问题了,可以考虑递推: 假设n个人,排出了m个名次,有f(n,m)种结果(1<=m<=n) 当m=1 f(n,m)=1 当n<m ...

  9. 编程:假设有n个人进行排名,允许并列排名,名次并列人的不同顺序算一种,总共有多少种排名?

    疯狂游戏笔试一道有趣的编程题:排名问题 题目描述 解题思路 代码 题目描述 假设有n个人进行排名,允许并列排名,名次并列人的不同顺序算一种,总共有多少种排名? 例:n=2,输出3,有:a>b,a ...

最新文章

  1. 用ASP.NET上传图片并生成带版权信息的缩略图
  2. 【割边缩点】解题报告:POJ - 3694 - Network(Tarjan割边缩点 + LCA + 并查集优化)
  3. python 入门笔记
  4. python提取个十百千位数字_实现人脸识别、人脸68个特征点提取,或许这个 Python 库能帮到你!...
  5. linux-free命令
  6. undefined reference to `pthread_create‘(linux下Clion使用thread报错)
  7. Map.putAll方法——追加另一个Map对象到当前Map集合
  8. dgl._ffi.base.DGLError: Cannot assign node feature “n_feat“ on device cuda:0 to a graph on device
  9. c# 注册了Ctrl+空格为热键,捕获后发送Ctrl+Shift
  10. 王思聪吃热狗火了,程序员开发各种恶搞小程序!王校长:我不要脸的啊
  11. Ali-tomcat之HSF框架Demo启动报错HSFServiceAddressNotFoundException
  12. 【安卓手机驱动无法安装则无法连接电脑,终极100%解决方法】ADB interfacm与 Andriod安装出现黄色感叹号
  13. 连接校园网后登不上图书馆里的SCI等网站问题
  14. 460. LFU缓存
  15. (OpenCV+Python)--目标跟踪,卡尔曼滤波+鼠标轨迹跟踪
  16. 搜索引擎推广公司引擎推广方法及技巧
  17. Ubuntu18.04键盘错乱问题
  18. 【urllib的使用(下)】
  19. 智慧交管可视化决策系统
  20. 非接环境(PPSE)和接触环境(PSE)的FCI有什么区别

热门文章

  1. 空海法师:阿含解脱道次第 解说讲稿 第廿六章 善用七觉支
  2. 微信小程序文件目录介绍
  3. 马士兵qbc和qbe示例
  4. 一篇文章玩转 RNN 网络 原理
  5. Lg手机在linux刷机,LG G3卡刷刷机详细图文教程
  6. 文字图片滚动代码-无缝滚动,强!!!
  7. 光盘显示0字节可用_HT光盘刻录管理系统~一套光盘智能管理的系统解决方案
  8. eCharts 自定义y轴数据
  9. 网站推广最实用不过的七种方法
  10. 在DCOM配置中找到Microsoft Office Word 97 - 2003 文档