明确题意:
将用户作答高难度试卷的得分在每份试卷作答记录内执行min-max归一化后缩放到[0,100]区间,并输出用户ID、试卷ID、归一化后分数平均值;
最后按照试卷ID升序、归一化分数降序输出。
问题分解:
- 统计每次高难度试卷被完成的分数以及该卷的最高最低分,生成子表 t_exam_record_min_max:
- 关联试卷作答表和试卷信息表:exam_record JOIN examination_info USING(exam_id)
- 筛选做完了高难度的记录:WHERE score IS NOT NULL AND difficulty="hard"
- 拼接上该试卷的最低分:MIN(score) over(PARTITION BY exam_id) as min_score
- 拼接上该试卷的最高分:MAX(score) over(PARTITION BY exam_id) as max_score
- 按用户ID和试卷ID分组:GROUP BY uid, exam_id
- 计算归一化后分数,需分情况讨论:
- 如果最高分和最低分相等,即只有一个分值:直接返回原分值
- 否则归一化后取整:ROUND(AVG((score - min_score) / (max_score - min_score) * 100))
细节问题:
- 表头重命名:as
- 按试卷ID升序、归一化分数降序排序:ORDER BY exam_id, avg_new_score DESC
完整代码:
SELECT uid, exam_id,
IF(max_score > min_score,
ROUND(AVG((score - min_score) / (max_score - min_score) * 100)),
score
) as avg_new_score
FROM (
SELECT uid, exam_id, score,
MIN(score) over(PARTITION BY exam_id) as min_score,
MAX(score) over(PARTITION BY exam_id) as max_score
FROM exam_record JOIN examination_info USING(exam_id)
WHERE score IS NOT NULL AND difficulty="hard"
) as t_exam_record_min_max -- 每次高难度试卷被完成的分数以及该卷的最大最小分
GROUP BY uid, exam_id
ORDER BY exam_id, avg_new_score DESC;