每日SQL一练#2023101802

94 阅读3分钟

题目来源:每类试卷得分前3名_牛客题霸_牛客网 (nowcoder.com)

我搬运下题目 现有试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间):

idexam_idtagdifficultydurationrelease_time
19001SQLhard602021-09-01 06:00:00
29002SQLhard602021-09-01 06:00:00
39003算法medium802021-09-01 10:00:00

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

iduidexam_idstart_timesubmit_timescore
1100190012021-09-01 09:01:012021-09-01 09:31:0078
2100290012021-09-01 09:01:012021-09-01 09:31:0081
3100290022021-09-01 12:01:012021-09-01 12:31:0181
4100390012021-09-01 19:01:012021-09-01 19:40:0186
5100390022021-09-01 12:01:012021-09-01 12:31:5189
6100490012021-09-01 19:01:012021-09-01 19:30:0185
7100590032021-09-01 12:01:012021-09-01 12:31:0285
8100690032021-09-07 10:01:012021-09-07 10:21:0184
9100390032021-09-08 12:01:012021-09-08 12:11:0140
10100390022021-09-01 14:01:01(NULL)(NULL)

找到每类试卷得分的前3名,如果两人最大分数相同,选择最小分数大者,如果还相同,选择uid大者。由示例数据结果输出如下:

tiduidranking
SQL10031
SQL10042
SQL10023
算法10051
算法10062
算法10033

解释:有作答得分记录的试卷tag有SQL和算法,SQL试卷用户1001、1002、1003、1004有作答得分,最高得分分别为81、81、89、85,最低得分分别为78、81、86、40,因此先按最高得分排名再按最低得分排名取前三为1003、1004、1002。

解答

按照试卷类型进行分组排序,然后取前三名的uid等信息。 排序规则取最大分数,如果最大分数相同则取最小分数的最大值,然后再取uid大者。

这里需要注意一下,试卷信息表examination_info中有两个SQL的数据行,是不同exam_id的,注意分组排序是不要使用这个字段,否则结果会不正确。

代码如下:


select * from
    (select
        b.tag as tid,
        a.uid,
        row_number() over(partition by b.tag order by max(a.score) desc, min(a.score) desc, uid desc) as ranking
    from
        exam_record as a
    inner join (select tag, exam_id from examination_info) as b
    on a.exam_id=b.exam_id and a.submit_time is not null
    group by a.uid, b.tag) as c
where ranking <=3
;