Mysql 查询实现成绩排名,相同分数名次相同,类似于rank()函数

近日系统要实现总分成绩排名,而且相同分数的学生排名要一样,在网上搜了一圈,没有找到合适的方法,只能靠自己实现了,这里提供两种方法

//还有其他排名方式可以借鉴https://blog.csdn.net/a9925/article/details/76804951

1、sql查询实现

测试如下:

mysql> select * from score ;
+----------+--------------+---------------------+--------------+-------+
| study_no | student_name | subject_id | subject_name | score |
+----------+--------------+---------------------+--------------+-------+
| student1 | student1 | CodeCourseSubject_0 | 语文 | 120 |
| student2 | student2 | CodeCourseSubject_0 | 语文 | 110 |
| student3 | student3 | CodeCourseSubject_0 | 语文 | 110 |
| student4 | student4 | CodeCourseSubject_0 | 语文 | 80 |
| student5 | student5 | CodeCourseSubject_0 | 语文 | 81 |
| student1 | student1 | CodeCourseSubject_2 | 英语 | 150 |
| student2 | student2 | CodeCourseSubject_2 | 英语 | 130 |
| student3 | student3 | CodeCourseSubject_2 | 英语 | 130 |
| student4 | student4 | CodeCourseSubject_2 | 英语 | 44 |
| student5 | student5 | CodeCourseSubject_2 | 英语 | 45 |
+----------+--------------+---------------------+--------------+-------+
10 rows in set

首先这里对科目显示进行了行列转换,并且对以学号study_no进行分组计算总分,并且按排名排序, 
sql如下:

SELECT @rownum:=@rownum+1 AS rownum,
   if(@total=total,@rank,@rank:=@rownum)as rank,
   @total:=total,
   A.*
   FROM (SELECT study_no AS studyNo,
        student_name AS studentName,
        SUM(score) AS total,
        SUM(IF(subject_id='CodeCourseSubject_0',score,0)) AS 语文,
        SUM(IF(subject_id='CodeCourseSubject_2',score,0)) AS 英语
        FROM score GROUP BY study_no ORDER BY total DESC
       )A,(SELECT @rank:=0,@rownum:=0,@total:=null)B

  

结果:

+--------+------+---------------+----------+-------------+-------+-------+-------+
| rownum | rank | @total:=total | studyNo | studentName | total | 语文 | 英语 |
+--------+------+---------------+----------+-------------+-------+-------+-------+
| 1 | 1 | 270.0 | student1 | student1 | 270.0 | 120.0 | 150.0 |
| 2 | 2 | 240.0 | student2 | student2 | 240.0 | 110.0 | 130.0 |
| 3 | 2 | 240.0 | student3 | student3 | 240.0 | 110.0 | 130.0 |
| 4 | 4 | 126.0 | student5 | student5 | 126.0 | 81.0 | 45.0 |
| 5 | 5 | 124.0 | student4 | student4 | 124.0 | 80.0 | 44.0 |
+--------+------+---------------+----------+-------------+-------+-------+-------+
5 rows in set

可见排名第二名有两个相同的分数,后面的排名自动往后移。

下面提供另外一种在程序中实现的方法:

2、程序实现

首先获得全班总分并且以降序排序

public List<Object[]> findAllTotalScore() {
String sql = "SELECT study_no,sum(score) AS total from score s ";
javax.persistence.Query query = em.createNativeQuery(sql);
return query.getResultList();
}

对获得的总分信息进行排序和封装成map(study_no,rank)

private Map<String, Long> rank(List<Object[]> objects) {
long previousRank = 1;
double total = 0;
//记录排名的map,map<study_no,排名>
Map<String, Long> rankMap = new HashMap<>();
for (int i = 0; i < objects.size(); i++) {
Object[] object = objects.get(i);
//计算名次,相同分数排名一样
if (total == (double) object[1]) {
rankMap.put(object[0].toString(), previousRank);
} else {
rankMap.put(object[0].toString(), i + 1L);
total = (double) object[1];
previousRank = i + 1;
}
}
return rankMap;
}

使用map直接根据学号就可以获得成绩排名。

转自:https://blog.csdn.net/a56508820/article/details/49663069

Mysql 查询实现成绩排名的更多相关文章

  1. sql 建表以及查询---复杂查询之成绩排名

    废话不说,直接建表 1.表Player USE T4st -- 设置当前数据库为T4st,以便访问sysobjects IF EXISTS(SELECT * FROM sysobjects WHERE ...

  2. mysql查询之分数排名

    编写一个 SQL 查询来实现分数排名.如果两个分数相同,则两个分数排名(Rank)相同 +----+-------+ | Id | Score | +----+-------+ | 1 | 3.50 ...

  3. mysql成绩排名

    关于mysql成绩排名,网上大部分只是order by简单排序,忽略了成绩相同并列名次的问题. 定义了一个表score结构为:

  4. MySQL实现排名并查询指定用户排名功能,并列排名功能

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

  5. MySQL中给自定义的字段查询结果添加排名的方法

    我正在用 MySQL 客户端的时候,突然想到如果可以给查询结果添加排名该多好啊,然后就找到了一个简单的解决办法. 下面是一个示例表的数据:  然后我们要根据 Roll_No 字段进行排序并给出排名,我 ...

  6. oracle根据成绩排名查询某个名次段的人员

    先说一下表结构  名字name  分数fenshu   表名test1,以下查询的是成绩排名为第三名和第四名,这个模板让你查随意排名段的人 select name,fenshu,mc from (se ...

  7. Mysql 查询练习

    Mysql 查询练习 ---创建班级表 create table class( cid int auto_increment primary key, caption ) )engine=innodb ...

  8. MySQL查询语句

    来源于网络... Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 ...

  9. mysql——查询练习

    Sutdent表的定义 字段名 字段描述 数据类型 主键 外键 非空 唯一 自增 Id 学号 INT(10) 是 否 是 是 是 Name 姓名 VARCHAR(20) 否 否 是 否 否 Sex 性 ...

随机推荐

  1. 一个完整Java Web项目背后的密码

    前言 最近自己做了几个Java Web项目,有公司的商业项目,也有个人做着玩的小项目,写篇文章记录总结一下收获,列举出在做项目的整个过程中,所需要用到的技能和知识点,带给还没有真正接触过完整Java ...

  2. Oracle Blob查询和插入

    注:本文来源于<Oracle Blob查询和插入> 插入 UPDATE cmm05 SET OUTFILE = to_blob('12345690'): 查询: SELECT utl_ra ...

  3. Confluence 6 CSS 编辑技巧

    开始编辑空间样式表 一个空间的样式表是你开始对 CSS 进行自定义编辑的好的开始.在空间样式表中,包含了你所有可以进行修改的元素.当你对空间样式表进行编辑的时候,空间样式表的修改只会对你修改的空间有效 ...

  4. Confluence 6 自定义主面板

    主面板(dashboard)是你 Confluence 站点的默认载入页面.这个页面能够给用户能够找到其他页面的所有必须的工具,重新进入未完成的工作或者快速导航到喜欢的空间和页面 站点的欢迎信息将会在 ...

  5. python之线程同步

    lock与rlock 使用lock不能连续两次获取锁,获取锁必须先释放锁.但是在一个线程中调用另一个函数时,在该函数中要继续操作共享的数据,这时获取锁就相当于连续执行两次获取锁,所以lock就不适用该 ...

  6. VUE开发请求本地数据的配置,旧版本dev-server.js,新版本webpack.dev.conf.js

    VUE开发请求本地数据的配置,早期的vue-lic下面有dev-server.js和dev-client.js两文件,请求本地数据在dev-server.js里配置,最新的vue-webpack-te ...

  7. Java的家庭记账本程序(E)

    日期:2019.2.9 博客期:032 星期二 今天是把程序的相关Bug补一补,嗯`: 1.添加了跳转说明 生成了一个对于成员的权限声明内容,用户再登陆界面点击Go按钮后,切换至说明页面,再次点击Go ...

  8. laravel 兜底路由

    在 Laravel 5.6 中,引入了兜底路由功能.所谓兜底路由,就是当路由文件中定义的所有路由都无法匹配用户请求的 URL 时,用来处理用户请求的路由,在此之前,Laravel 都会通过异常处理器为 ...

  9. Chrome浏览器常用键盘快捷键介绍

    很多人喜欢使用键盘快捷键来操作电脑,因为在熟练的情况下,使用键盘会比使用鼠标点击更快.更高效.本文对Chrome浏览器常用的快捷键做个说明. 标签页和窗口快捷键 1.  Ctrl + n 打开新窗口 ...

  10. 对象存储服务(Object Storage Service,简称 OSS)

    阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量.安全.低成本.高可靠的云存储服务.它具有与平台无关的RESTful API接口,能够提供99.99 ...