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
相关推荐
小猿姐4 小时前
实测对比:哪款开源 Kubernetes MySQL Operator 最值得用?(2026 深度评测)
数据库·mysql·云原生
倔强的石头_6 小时前
从 “存得下” 到 “算得快”:工业物联网需要新一代时序数据平台
数据库
TDengine (老段)7 小时前
TDengine IDMP 可视化 —— 分享
大数据·数据库·人工智能·时序数据库·tdengine·涛思数据·时序数据
GottdesKrieges8 小时前
OceanBase数据库备份配置
数据库·oceanbase
SPC的存折8 小时前
MySQL 8组复制完全指南
linux·运维·服务器·数据库·mysql
运维行者_8 小时前
OpManager MSP NetFlow Analyzer集成解决方案,应对多客户端网络流量监控挑战
大数据·运维·服务器·网络·数据库·自动化·运维开发
炸炸鱼.10 小时前
Python 操作 MySQL 数据库
android·数据库·python·adb
softshow102610 小时前
Etsy 把 1000 个 MySQL 分片迁进 Vitess
数据库·mysql
Ronaldinho Gaúch10 小时前
MySQL基础
数据库·mysql
不剪发的Tony老师11 小时前
Noir:一款键盘驱动的现代化数据库管理工具
数据库·sql