mysql 同一个字段作为2种不同的if条件作判断_一文解决所有MySQL分类排名问题

本文介绍了如何在MySQL中进行分类排名,包括子查询、自连接、自定义变量和窗口函数四种方法。通过示例展示了如何根据成绩表按课程对学生成绩进行高效排序,并讨论了各种方法的效率和适用场景,特别是自定义变量和窗口函数在处理同分排名需求时的优势。
摘要由CSDN通过智能技术生成
来自公众号:小数志

导读

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

本文介绍4种分类排名方式:子查询、自连接、自定义变量以及MySQL8.0窗口函数。

01 需求介绍

考虑MySQL中的一个经典应用:给定一个学生考试成绩表,要实现对学生按课程依成绩高低进行排序。为了简单起见,仅给定成绩表,而不考虑可能关联的学生信息表、课程信息表和教师信息表等,且成绩表中仅创建3个关键字段:

  • cid:课程id,int型,共5门课程
  • sid:学生id,int型,共8872名学生
  • score:成绩,int型,共22366条成绩信息,分布于10-100之间

be22084c002c7f3945005d285b3f03f4.png

为了逐步分析,初始状态不添加主键,也不建立任何索引。

02 子查询实现这一需求的最直接想法是通过子查询,对每个分数进行统计:统计表中有多少分数比其更高,那么该分数的排名就是更高分数计数+1。如果要区分课程排名,那么统计表时只需增加一个限制课程id相等的约束条件即可。
1SELECT
2    a.*, ( SELECT COUNT(score)+1 FROM scores WHERE cid = a.cid AND score > a.score ) AS 'rank' 
3FROM
4    scores a 
5ORDER BY
6    a.cid,  a.score DESC;
需注意的是,在子查询约束条件中要求 score > a.score以及 COUNT()+1,表示统计的是比该成绩更高的计数+1,例如对于90、80、80、70……这样的分数得到排名结果是1,2,2,4……;如果选用 score >= a.score和 COUNT()作为排名条件,那么得到结果是1,3,3,4……
在未添加任何索引的情况下,这个查询速度是相当慢的,耗时 120s。

664e2ef49a7bd222c3dacc8c7089a8bf.png

未添加索引时的子查询执行计划

优化查询的第一想法当然是添加索引:虽然外层查询未用到任何where约束条件,但子查询中用到了cid和score两个字段判断,于是考虑添加索引:
1CREATE INDEX idc ON scores(cid);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值