查询各科分数最高的科目名称,学生学号,姓名,分数,排名
1.有三个表student(学生表),sc(成绩表),course(课程表),其定义和数据如下
student:
sidsnamesagessex
01赵雷1990-01-01男02钱电1990-12-21男03孙风1990-12-20男04李云1990-12-06男05周梅1991-12-01女06吴兰1992-01-01女07郑竹1989-01-01女09张三2017-12-20女10李四2017-12-25女11李四2012-06-06女12赵六2013-06-13女13孙七2014-06-01女
sc:
sidcidscore
010180010290010399020170020260020380030180030280030380040150040230040320040460050176050287060131060334070289070398
course:
cidcnametid
01语文0202数学0103英语0304生理学04
解题思路:
1.首先给sc表按照cid分区按照分数降序排序,最后加个排名
select cid
,sid
,score
,row_number
() over (partition by CId
order by score
desc) ranks
from sc
这里不会row_number() over()函数的同学自行百度,搞清楚rank(),dense_rank(),row_number()的区别,以及配上over()函数的用法。
查询结果为:
2.然后和student表、course表连接起来,如果有多个最高分,按照名字的先后顺序排序。
select sc
.cid
,c
.cname
,sc
.sid
,s
.sname
,sc
.score
,row_number
() over (partition by sc
.CId
order by sc
.score
desc,s
.sname
) ranks
from sc
,student s
,course c
where s
.sid
= sc
.sid
and sc
.cid
=c
.cid
查询的结果为:
3.要选取每科的最高分,那么我们把上面查询的结果看做一个表,查询条件为ranks=1,那么就是选取的每科的最高分,如果说题目是选取每科的前3名,我们只要加条件ranks<=3就可以了,我们来看代码。
select *
from(
select sc
.cid
,c
.cname
,sc
.sid
,s
.sname
,sc
.score
,row_number
() over (partition by sc
.CId
order by sc
.score
desc,s
.sname
) ranks
from sc
,student s
,course c
where s
.sid
= sc
.sid
and sc
.cid
=c
.cid
)a
where ranks
=1
查询结果:
结果没问题,我们来看看每科前3的sql和查询结果。
select *
from(
select sc
.cid
,c
.cname
,sc
.sid
,s
.sname
,sc
.score
,row_number
() over (partition by sc
.CId
order by sc
.score
desc,s
.sname
) ranks
from sc
,student s
,course c
where s
.sid
= sc
.sid
and sc
.cid
=c
.cid
)a
where ranks
<=3
查询结果:
结果没毛病,如果大家有更好的方法,或者更高效的方法可以一起讨论,欢迎指正。