当前位置: 首页 > news >正文

SQL180 每类试卷得分前3名

描述

现有试卷信息表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
2100190012021-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大者。由示例数据结果输出如下:

tag

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


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

SELECTtag,uid,ranking
FROM(SELECTei.tag,er.uid,MAX(er.score) AS max_score, -- 每个用户在该类别下的最高分MIN(er.score) AS min_score, -- 最低分(用于平局决胜)ROW_NUMBER() OVER (PARTITION BYei.tagORDER BYMAX(er.score) DESC, -- 先按最高分排序MIN(er.score) DESC, -- 再按最低分排序er.uid DESC -- 最后按 uid 排序) AS rankingFROMexamination_info eiJOIN exam_record er USING (exam_id)WHEREer.score IS NOT NULL -- 只统计有得分的记录GROUP BYei.tag,er.uid -- 按“类别+用户”分组) t
WHEREranking <= 3 -- 取前3名
ORDER BYtag,ranking;

窗口函数

1. 窗口函数基本格式

函数名() OVER (PARTITION BY 分组字段   -- 按什么分组(可选)ORDER BY 排序字段       -- 按什么排序(必选)
) 

👉 就像“分组 + 排序 + 计算”,但不改变行数


2. 常用函数

函数作用
ROW_NUMBER()排名:1,2,3,4…(不并列)
RANK()排名:1,2,2,4…(并列,跳号)
DENSE_RANK()排名:1,2,2,3…(并列,不跳号)

3. 举个例子

ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC
)

意思:

  • 每个班(class)单独排名
  • 按分数从高到低排
  • 返回排名:第1名、第2名…

4. 注意!

  • 窗口函数不能直接在 WHERE 里用
  • 要用的话,得套一层子查询
SELECT * FROM (SELECT ..., ROW_NUMBER() OVER (...) AS rnFROM table
) t
WHERE rn <= 3;  -- ✅ 这样才能用

✅ 一句话记住

PARTITION BY 分组,ORDER BY 排序,ROW_NUMBER() 给每行打上排名。


http://www.xdnf.cn/news/1285399.html

相关文章:

  • 【Redis在在线表单提交防重复机制中的应用策略】
  • 移动端调用大模型详解
  • Web学习笔记5
  • [git] 重配ssh key | 解决冲突
  • 一键生成 Android 适配不同分辨率尺寸的图片
  • Wireshark专家模式定位网络故障:14种TCP异常深度解剖
  • Ceph存储池参数中pg_num和pgp_num的关系
  • 终端安全检测和防御技术
  • 华为发布AI推理新技术,降低对HBM内存依赖
  • 负载均衡详解
  • 纯CSS+JS制作抽奖大转盘
  • C#教程之NPOI读写excel文件XLS,XLSX格式
  • 【vue(二)Vuex】
  • damn the jvm again(2)
  • 《Qwen2.5-VL 》论文精读笔记
  • 【测试】Bug+设计测试用例
  • 【Bug经验分享】由jsonObject-TypeReference引发的序列化问题
  • 无人机在环保监测中的应用:低空经济发展的智能监测与高效治理
  • 从0开始的中后台管理系统-5(菜单的路径绑定以及角色页面的实现)
  • Javase 之 字符串String类
  • 《飞算Java AI:从安装到需求转实战项目详细教学》
  • 机器学习算法篇(十):TF-IDF算法详解与应用实战
  • 线性代数 · 矩阵 | 最小多项式
  • IoTDB与传统数据库的核心区别
  • Spring Boot项目使用WebClient调用第三方接口详细教程
  • Elasticsearch Node.js 客户端连接指南(Connecting)
  • 一起来聊聊GPT-5
  • 面试经典150题[001]:合并两个有序数组(LeetCode 88)
  • 从零开始手搓一个GPT大语言模型:从理论到实践的完整指南(一)
  • 安全合规5--终端安全检测和防御技术