题解 | #对试卷得分做min-max归一化#

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

http://www.nowcoder.com/practice/2b7acdc7d1b9435bac377c1dcb3085d6

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

题目主要信息:

  • min-max标准化: ximin(xi)max(xi)min(xi)\frac{x_i - min(x_i)}{max(x_i)-min(x_i)}
  • 将用户作答高难度试卷的得分在每份试卷作答记录内执行min-max归一化后缩放到[0,100][0,100]区间,并输出用户ID、试卷ID、归一化后分数平均值
  • 最后按照试卷ID升序、归一化分数降序输出

问题拆分:

  • 筛选出难度为困难的每个试卷id的最大分数和最小分数:
    • 要筛选的是每个试卷ID下的最大与最小分数,因此要以exam_id分组。知识点:group by
    • 难度信息和得分信息再分别在两个表中,因此通过exam_id将二者连接起来。知识点:join...on...
    • 筛选难度为困难级别的。知识点:where
    • 对每个组求最大最小得分。 max(exam_record.score) as max_score, min(exam_record.score) as min_score 知识点:max()、min()
    • 筛选结果记为id_and_max_min_table
  • 每份试卷的最大最小得分与每个用户的得分分布在两个表中,因此通过exam_id将表id_and_max_min_table与exam_record连接起来。知识点:join...on...
  • 从连接后的表中选出用户ID、试卷ID及每个分数的归一化结果:
    • 求每个用户对于每份试卷的归一化结果,因此要以uid和exam_id分组。 知识点:group by
    • uid和exam_id直接获取。
    • 使用if函数判断该试卷最大最小值是否相等,然后做归一化计算。if(max_score = min_score, score, round(avg((score - min_score) / (max_score - min_score)) * 100)) as avg_new_score 知识点:if、avg()、round()
    • 筛选条件是这个用户的得分不能用空。知识点:where
  • 按照先试卷ID升序后新分数降序的次序输出。order by exam_id asc, avg_new_score desc 知识点:order by

代码:

select uid,
       e_r.exam_id as exam_id,
       if(max_score = min_score, score, round(avg((score - min_score) / (max_score - min_score)) * 100)) as avg_new_score
from exam_record e_r join(
    select exam_record.exam_id,
           max(exam_record.score) as max_score,
           min(exam_record.score) as min_score
    from exam_record join examination_info
    on exam_record.exam_id = examination_info.exam_id
    where examination_info.difficulty = 'hard'
    group by exam_record.exam_id
) id_and_max_min_table
on e_r.exam_id = id_and_max_min_table.exam_id
where score is not null 
group by uid, exam_id
order by exam_id asc, avg_new_score desc
孤帆远影碧空尽 文章被收录于专栏

牛客网各类题单题解~

全部评论
把条件里面的score改成round(avg(score))就好了, if(max_score = min_score,round(avg(score)), round(avg((score - min_score) / (max_score - min_score)) * 100)) as avg_new_score
2 回复 分享
发布于 2022-03-04 10:15
这大师不行啊,不愧是摸鱼大师。 if要放到avg里面去,不然只有一个分数的都没有聚合到。
点赞 回复 分享
发布于 2022-04-06 22:59
select err.uid,err.exam_id, if(max_score<>min_score,round(avg((err.score-min_score)/(max_score-min_score))*100,0),score) as avg_new_score from exam_record err join( select er.exam_id as exam_id, max(er.score) as max_score, min(er.score) as min_score from exam_record er left join examination_info ei on er.exam_id=ei.exam_id where ei.difficulty='hard' group by exam_id ) a on err.exam_id=a.exam_id where err.score is not null group by err.uid,err.exam_id order by exam_id,avg_new_score desc
点赞 回复 分享
发布于 2022-02-14 10:13
最后用 having avg_new_score is not null 筛选
点赞 回复 分享
发布于 2021-12-06 21:55
报错啊
点赞 回复 分享
发布于 2021-11-21 02:18

相关推荐

10-17 09:06
门头沟学院 Java
8527睿:有些地方感觉不太契合实际啊。简单看看第二个项目那里。 比如canal流式读取数据库日志进行缓存同步那里。可不可以加个消息中间件来确保SQL语句的削峰填谷。一般都是canal+消息中间件 双层鉴权登录那里,描述有点模糊,登录是鉴权的前提唉,后面功能都在说是登录,鉴权没有啊
点赞 评论 收藏
分享
评论
5
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务