SQL181 第二快/慢用时之差大于试卷时长一半的试卷

描述

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

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

找到第二快和第二慢用时之差大于等于试卷时长的一半的试卷信息,按试卷ID降序排序。由示例数据结果输出如下:

|---------|----------|---------------------|
| exam_id | duration | release_time |
| 9001 | 60 | 2021-09-01 06:00:00 |

解释:试卷9001被作答用时有58分钟、50分钟、30分1秒、11分钟、10分钟,第二快和第二慢用时之差为50分钟-11分钟=39分钟,试卷时长为60分钟,因此满足大于试卷时长一半的条件,输出试卷ID、时长、发布时间。

复制代码
select
    exam_id,
    duration,
    release_time
from
    (
        select
            exam_id,
            duration,
            release_time,
            sum(
                case
                    when rk_desc = 2 then time_diff
                    when rk_asc = 2 then - time_diff
                    else 0
                end
            ) as timre
        from
            (
                select
                    a.exam_id,
                    timestampdiff(minute, b.start_time, b.submit_time) time_diff,
                    a.duration,
                    a.release_time,
                    row_number() over (
                        partition by
                            a.exam_id
                        order by
                            timestampdiff(minute, b.start_time, b.submit_time) desc
                    ) as rk_desc,
                    row_number() over (
                        partition by
                            a.exam_id
                        order by
                            timestampdiff(minute, b.start_time, b.submit_time) asc
                    ) as rk_asc
                from
                    examination_info a
                    join exam_record b on a.exam_id = b.exam_id
                where
                    b.submit_time is not null
            ) t1
        group by
            exam_id
    ) t2
where
    timre >= (duration / 2)
order by
    exam_id desc;

关键 SQL 逻辑拆解

✅ 第一步:计算每位考生的答题时长(分钟)
复制代码
timestampdiff(minute, start_time, submit_time) as time_diff
  • 使用 TIMESTAMPDIFF(MINUTE, ...) 计算答题持续时间。
✅ 第二步:对每场考试分别排序,找出"第二长"和"第二短"
复制代码
row_number() over (
    partition by exam_id 
    order by time_diff desc
) as rk_desc  -- 从长到短:最长是1,第二长是2

row_number() over (
    partition by exam_id 
    order by time_diff asc
) as rk_asc   -- 从短到长:最短是1,第二短是2
  • 利用窗口函数 ROW_NUMBER() 实现排名。
  • 注意:rk_desc=2 表示第二慢提交(答题时间第二长)。
✅ 第三步:条件聚合,提取"第二长 - 第二短"时间差
复制代码
sum(
    case 
        when rk_desc = 2 then time_diff
        when rk_asc = 2 then -time_diff
        else 0 
    end
) as timre
  • 巧妙利用 sum(case ...) 实现"提取特定排名值"的效果。
  • 最终结果:timre = 第二长答题时间 - 第二短答题时间

💡 技巧提示:这种"条件求和"是 SQL 中实现"取第 N 值"的常用技巧。

✅ 第四步:筛选满足条件的考试
复制代码
where timre >= (duration / 2)
  • 只保留差异较大的考试。
✅ 第五步:输出并排序
复制代码
select exam_id, duration, release_time
order by exam_id desc
相关推荐
倔强的石头_11 小时前
kingbase备份与恢复实战(二)—— sys_dump库级逻辑备份与恢复(Windows详细步骤)
数据库
jiayou642 天前
KingbaseES 实战:深度解析数据库对象访问权限管理
数据库
李广坤3 天前
MySQL 大表字段变更实践(改名 + 改类型 + 改长度)
数据库
爱可生开源社区4 天前
2026 年,优秀的 DBA 需要具备哪些素质?
数据库·人工智能·dba
随逸1774 天前
《从零搭建NestJS项目》
数据库·typescript
加号34 天前
windows系统下mysql多源数据库同步部署
数据库·windows·mysql
シ風箏4 天前
MySQL【部署 04】Docker部署 MySQL8.0.32 版本(网盘镜像及启动命令分享)
数据库·mysql·docker
李慕婉学姐4 天前
Springboot智慧社区系统设计与开发6n99s526(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·spring boot·后端
百锦再4 天前
Django实现接口token检测的实现方案
数据库·python·django·sqlite·flask·fastapi·pip
tryCbest4 天前
数据库SQL学习
数据库·sql