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

SQL186 对试卷得分做min-max归一化

一、题目描述

表结构

  • examination_info:试卷信息表(exam_idtagdifficultydurationrelease_time
  • exam_record:作答记录表(uidexam_idstart_timesubmit_timescore

 要求

  1. 只处理 高难度(difficulty = 'hard')的试卷
  2. 对每份高难度试卷的所有作答记录,进行 Min-Max 归一化,公式:

    new_score=score−min⁡(score)max⁡(score)−min⁡(score)×100new_score=max(score)−min(score)score−min(score)​×100

  3. 特殊情况:如果某试卷只有一条有效得分记录,则归一化后分数 = 原分数
  4. 输出:uidexam_idavg_new_score(每个用户在每份试卷上的平均新分数,只保留整数部分
  5. 排序:按 exam_id 升序,avg_new_score 降序

二、正确 SQL 解法

SELECT uid, exam_id, ROUND(SUM(max_min) / COUNT(max_min), 0) AS avg_new_score
FROM (SELECT exam_id, uid, score,IF(min_x = max_x, score, (score - min_x) * 100 / (max_x - min_x)) AS max_minFROM (SELECT uid, a.exam_id, score,MIN(score) OVER (PARTITION BY a.exam_id) AS min_x,MAX(score) OVER (PARTITION BY a.exam_id) AS max_xFROM exam_record aLEFT JOIN examination_info b ON a.exam_id = b.exam_idWHERE b.difficulty = 'hard'AND a.score IS NOT NULL) t1
) t2
GROUP BY exam_id, uid
ORDER BY exam_id, avg_new_score DESC;

 三、分步解析(核心!)

我们像“搭积木”一样,从内到外一步步构建。


 第一步:筛选高难度试卷的有效作答记录

SELECT uid, a.exam_id, score,MIN(score) OVER (PARTITION BY a.exam_id) AS min_x,MAX(score) OVER (PARTITION BY a.exam_id) AS max_x
FROM exam_record a
LEFT JOIN examination_info b ON a.exam_id = b.exam_id
WHERE b.difficulty = 'hard'AND a.score IS NOT NULL
 做了什么?
  1. LEFT JOIN 关联两张表,获取试卷难度
  2. WHERE b.difficulty = 'hard':只保留高难度试卷
  3. AND a.score IS NOT NULL:排除未交卷记录(如 submit_time 为 NULL
  4. 使用窗口函数:
    • MIN(score) OVER (PARTITION BY exam_id) → 每份试卷的最低分
    • MAX(score) OVER (PARTITION BY exam_id) → 每份试卷的最高分
 输出示例(t1):
uidexam_idscoremin_xmax_x
10019001906890
10039001686890
10019001896890
10039002756090
10049002606090
...............

 这是“第一层中间结果”,我们拿到了每条记录对应的 minmax


第二步:计算归一化后的分数(关键!)

IF(min_x = max_x, score, (score - min_x) * 100 / (max_x - min_x)) AS max_min
为什么用 IF

因为题目说:

“如果某个试卷作答记录中只有一个得分,那么无需使用公式,归一化并缩放后分数仍为原分数”

这意味着:

  • 如果 min_x == max_x(即所有分都一样,或只有一条记录),就直接用原分
  • 否则,使用归一化公式
计算过程(以 9001 为例):
scoremin_xmax_xnew_score
906890(90-68)/(90-68)*100 = 100
686890(68-68)/22*100 = 0
896890(89-68)/22*100 ≈ 95.45 → 但先保留,后面再处理

 注意:这里我们先不四舍五入,因为后面还要平均。


 第三步:对每个用户在每份试卷上的新分数求平均

SELECT uid, exam_id, ROUND(SUM(max_min) / COUNT(max_min), 0) AS avg_new_score
FROM ( ... ) t2
GROUP BY exam_id, uid
 做了什么?
  • GROUP BY exam_id, uid:按“试卷+用户”分组
  • SUM(max_min) / COUNT(max_min):计算平均值(等价于 AVG(max_min)
  • ROUND(..., 0):四舍五入到整数位
 示例(9001):
  • 用户 1001:有两条记录,100 和 95.45 → 平均 ≈ 97.73 → ROUND(97.73, 0) = 98
  • 用户 1003:只有一条 0 → 平均 = 0 → 0

完全符合题目要求。


 第四步:排序输出

ORDER BY exam_id, avg_new_score DESC
  • 先按试卷 ID 升序
  • 再按归一化后平均分降序

四、常见错误与避坑指南

错误后果正确做法
忘记 score IS NOT NULL包含未交卷记录,影响 min/max必须过滤 score 为 NULL 的行
忘记 difficulty = 'hard'包含中等难度试卷必须关联 examination_info 并筛选
直接用 AVG() 而不 ROUND(..., 0)小数部分保留,不符合“只保留整数”必须 ROUND(..., 0)
不处理 min_x = max_x 的情况分母为 0 报错用 IF 判断边界情况
在窗口函数中用 GROUP BY逻辑混乱窗口函数用于“每行计算”,不替代 GROUP BY

五、核心知识点总结

1. Min-Max 归一化公式(牢记!)

new_value=old_value−min⁡max⁡−min⁡×(new_max−new_min)+new_minnew_value=max−minold_value−min​×(new_max−new_min)+new_min

本题中:

  • new_min = 0
  • new_max = 100
  • 所以简化为:(score - min) * 100 / (max - min)

2. 窗口函数 vs 聚合函数

类型是否减少行数用途
MIN()/MAX() 聚合配合 GROUP BY,返回一行
MIN() OVER() 窗口每行都带上 min 值,用于后续计算

 本题必须用窗口函数,因为我们要保留每一行记录,同时知道全局 min/max

3. IF 条件判断(MySQL)

IF(条件, 真值, 假值)

等价于其他数据库的 CASE WHEN


🎯 六、举一反三

想要 Z-score 标准化?

(score - AVG(score) OVER (PARTITION BY exam_id)) / STDDEV(score) OVER (...)

想要缩放到 [10, 90]?

IF(min_x = max_x, 50, (score - min_x) * 80 / (max - min) + 10)

想要排除异常值?

先用 PERCENT_RANK()Z-score 过滤离群值,再归一化。

http://www.dtcms.com/a/528562.html

相关文章:

  • 哪家开发app好有南昌网站优化公司
  • vue3 npm run dev局域网可以访问,vue启动设置局域网访问,
  • 网站建设续费催款通知书哈尔滨微信网站开发
  • NLP之Embedding:Youtu-Embedding的简介、安装和使用方法、案例应用之详细攻略
  • 做网站需要学哪些语言wordpress sina
  • Redis常见指令
  • 机器学习02——环境安装
  • 网站可以用中国二字做抬头吗WordPress 评论框表情
  • 随笔——记一次常见的浮点数精度问题到Grisu3初识
  • 【git】rebase 和 merge 区别及使用建议
  • 机器学习催化剂设计!
  • Agent Zero:重新定义AI Agent的有机生长框架——从“预设工具“到“自我进化“的范式革命
  • 脚本更新--CosMx、Xenium的邻域通讯分析(R版本)
  • VS Code搭建C/C++开发调试环境-Windows
  • 怎么把自己做的网站发布到网上网站建设专题页面
  • 面向智慧农业的自主移动果蔬采摘机器人:融合视觉识别与自动驾驶的智能化农作系统研究
  • 厦门专业网站设计公司低价网站建设推广优化
  • ClickHouse 介绍
  • 何时在 ClickHouse 中使用 ARRAY JOIN
  • Stream流中.filter和.map的用法区别
  • 在万网上域名了怎么做网站网页设计与制作工资多少
  • 哈尔滨网站建设制作费用百度推广销售
  • FireFox如何滚动截屏?
  • 【Linux】Tomcat基本配置
  • 网站建设的系统分析有哪些好的建站平台
  • 【大模型推理】ScheduleBatch 学习
  • 【经典书籍】C++ Primer 第19章特殊工具与技术精华讲解
  • JAVA面试汇总(二)多线程(五)
  • 怎样设计网站模板网站 建设初步
  • 网站建设所需的硬件设备网站运营工作是干什么的