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
相关推荐
毕设十刻10 小时前
基于Vue的迅读网上书城22f4d(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
薛定谔的猫198211 小时前
Langchain(十二)LangGraph 实战入门:用流程图思维构建 LLM 工作流
数据库·microsoft
坐吃山猪11 小时前
ChromaDB02-代码实战
数据库·向量数据库·chromadb
摇滚侠11 小时前
MySQL 中 utf8mb4 字符集,字母a占几个字节,一个汉字占几个字节 / MySQL 中 utf8mb3 字符集,字母a占几个字节,一个汉字占几个字节
数据库·mysql
ChineHe11 小时前
Redis数据类型篇001_数据类型梳理与选择指南
数据库·redis·缓存
Antoine-zxt11 小时前
MySQL CPU飙升至500%的深度排查与优化实践
数据库·mysql
Awkwardx12 小时前
MySQL数据库—MySQL基本查询
数据库·mysql
夜流冰12 小时前
Excel - MS Support for Excel: 2 Collaborate
数据库·windows·excel
轻微的风格艾丝凡12 小时前
嵌入式定时器计时技巧:用有符号数省略溢出判断的底层逻辑与实践
数据库·算法·dsp开发·嵌入式软件
Lonely丶墨轩12 小时前
从登录入口窥见架构:一个企业级双Token认证系统的深度拆解
java·数据库·sql