当前位置: 首页 > 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.lryc.cn/news/618991.html

相关文章:

  • 单例模式,动态代理,微服务原理
  • 大数据技术入门精讲(Hadoop+Spark)
  • 当机械臂装上「智能大脑」:Deepoc具身智能模型如何重构传统自动化​
  • JavaEE 初阶第十八期:叩开网络世界的大门(上)
  • 自己动手造个球平衡机器人
  • 13.深度学习——Minst手写数字识别
  • 【自动化运维神器Ansible】playbook文件内变量定义全流程解析
  • 实时域自适应检测SOTA方案RT-DATR,刷新多个跨域检测榜单!
  • wordpress数据库文件sql导入时出现#1253错误
  • Java数据结构之ArrayList
  • 嵌入式分享合集136
  • 移动端调用大模型详解
  • 关于淘宝双十一
  • 数据分析小白训练营:基于python编程语言的Numpy库介绍(第三方库)(上篇)
  • DuckDB读取xlsx格式数据的方法比较
  • 【SpringBoot】MyBatis 动态 sql
  • 如何应对CAN总线冲突和数据丢包
  • 【c++深入系列】:万字详解模版(下)
  • 【项目设计】高并发内存池
  • AI赋能IT服务管理:从被动响应到智能驱动的跃迁
  • Linux驱动开发probe字符设备的完整创建流程
  • 【前端八股文面试题】【JavaScript篇7】什么是JavaScript的原型、原型链? 有什么特点
  • JavaScript Array.prototype.flatMap ():数组 “扁平化 + 映射” 的高效组合拳
  • 无人机三维路径规划
  • 2020/12 JLPT听力原文 问题一 4番
  • MyBatis-Plus——SQL注入器
  • LintCode第1526-N叉树的前序遍历
  • RabbitMQ面试精讲 Day 20:RabbitMQ压测与性能评估
  • 【游戏优化笔记】开发中如何减少建筑和树木等环境元素的资源消耗?
  • 行业热点丨智能仿真时代:电子工程多物理场解决方案创新实践