mysql查询学科_查询出各个学科的前3名的同学信息的Sql

查找各个学科的成绩前3名的学生信息Sql,有2种方法,一种是利用sql的row_number() over()函数,另一种是用子查询,

表设计如下

e0ea22e52f59edcc695346b1556193de.png

如果不考虑各个学科的成绩有并列的情况的话,有如下两种方法进行查询,

1. ROW_NUMBER() OVER()函数

select * from (

select ROW_NUMBER() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

) as a

where rownum < 4

order by CourseName

结果如下图

51e2dcc12735f8581d5933d8917e690e.png

2. 子查询

select * from MyTest m

where id in (select top 3 id from MyTest n where n.CourseName = m.CourseName order by Score desc)

order by CourseName,Score desc

结果如下图

6e0775b50394df4766883b4d91728d3d.png

可以看出,当各个学科的前三名所得分数没有相同时,以上2种方法都可以,但如果某个科目有相同的分数时,

所得结果就会出现不一致的情况,如张三和刘德华的数学分数都是70分,第一个查出的前三名包括刘德华,而第二个查询前三名却包括张三

要解决以上问题,可以运用Sql的 rank() OVER()或dense_rank() OVER()函数进行查询,

具体是使用这2个方法中的哪一个要看具体的结果需求,可以先了解下这2个函数的具体用法再决定用哪个更合适,

我这里以 rank() OVER() 函数为例,解决方法如下:

1.

select * from (

select rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

) as a

where rownum < 4

order by CourseName

结果如下图

d9b609b37dd081fa3d71877aa01ff7f3.png

这时就可以看到数学一课中,得分都为70的刘德华和张三都被查询到了

如果使用dense_rank() OVER()函数,语句如下

select * from (

select dense_rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

) as a

where rownum < 4

order by CourseName

结果如下图

a48c5cc13219290a7b801bed96aaa1af.png

原因在于dense_rank() OVER()与 rank() OVER()对于重复的数据编号时的处理方式不同,

rank()碰到重复的记录时编码下一个记录时会跳数字,而dense_rank() OVER()则不会,

如用rank() OVER()如下

select rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

结果如下图

bf13218131e68fa8831be9f5a6d7b279.png

注意看数学学科的按分数排名的规则

如果使用dense_rank() OVER(),

select dense_rank() OVER(partition by CourseName ORDER BY Score desc) AS rownum,* from MyTest

结果如下图

d9d5eb7249871e824e40fbc95bbb3f74.png

另外,对于子查询方式,对于重复分数的记录,如果我们查询各个学科的前3名时也想查询出来,可以使用以下改进的语句,如

with a as (

select distinct CourseName,Score from MyTest m

where id in (select top 3 id from MyTest n where n.CourseName = m.CourseName order by Score desc)

--order by CourseName,Score desc

)

select m.*

from MyTest m join a n

on m.CourseName = n.CourseName

and m.Score = n.Score

order by CourseName,Score desc

结果如下图

e4b1dd746b7c8bb030c38a6ecaae8950.png

这种写法类似于使用Sql函数rank() OVER()的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值