题解 | #每类试卷得分前3名#

一、表、字段

examination_info (试卷信息表) id (自增ID) exam_id (试卷ID) tag (类别标签) difficulty (难度) duration (时长) release_time (发布时间)

exam_record (试卷作答记录表) id (自增ID) uid (用户ID) start_time (开始时间) exam_id (试卷ID) submit_time (提交时间) score (得分)

二、条件

1、找到每类试卷得分的前3名

使用left...join...on 将两个表连接 起来 然后根据tag类别标签和uid用户ID进行分组

select 
	te.tag,
    tem.uid 
from 
	examination_info te 
left join 
	exam_record tem 
on 
	te.exam_id = tem.exam_id   
group by 
	te.tag,tem.uid 

2、如果两人最大分数相同,选择最小分数大者

3、如果还相同,选择uid大者

是根据类别标签进行窗口分组 也是根据类别标签窗口排序 遇到有重复的 先按照最大分数排序、依次按照最小分数、uid排序 所以 条件如下:

利用row_number()over(partition by ...order by....) 进行排名 排序 row_number开窗函数排序规则是 遇到有重复的数据 比如1、2、3、4的规则进行排名、排序 rank()排序、排名规则是 遇到有重复数据的 比如 1,、2、2、4 row_number()排序、排名排名规则是 遇到有重复数据的 比如1、2、2、3 如果不太明白开窗函数的 可看这篇文章 https://blog.csdn.net/nanyangnongye/article/details/122322488

row_number()
over(partition by tag  order by tag,
     max(score) desc,
     min(score) desc,
     uid desc)

所以 sql组装如下:

select 
	te.tag,
    tem.uid,
    row_number()
	over(partition by tag  order by tag,
    max(score) desc,
    min(score) desc,
    uid desc) as ranking
from 
	examination_info te 
left join 
	exam_record tem 
on 
	te.exam_id = tem.exam_id   
group by 
	te.tag,tem.uid 

三、最终题解

但是由于开窗函数后面不能直接跟having 即 不能使用包含窗口函数的表达式的别名 所以将组装sql 使用with 表名 as()临时表的方式 进行条件筛选

with temp as(
select 
	te.tag,
    tem.uid,
    row_number()
	over(partition by tag  order by tag,
    max(score) desc,
    min(score) desc,
    uid desc) as ranking
from 
	examination_info te 
left join 
	exam_record tem 
on 
	te.exam_id = tem.exam_id   
group by 
	te.tag,tem.uid 
)select * from temp where ranking <= 3 

全部评论

相关推荐

11-28 16:13
门头沟学院 Java
程序员小白条:年底了,都差不多了
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务