牛客网SQL进阶123:高难度试卷的得分的截断平均值

官网链接:

SQL类别高难度试卷得分的截断平均值_牛客题霸_牛客网牛客的运营同学想要查看大家在SQL类别中高难度试卷的得分情况。 请你帮她从exam_。题目来自【牛客题霸】https://www.nowcoder.com/practice/a690f76a718242fd80757115d305be45?tpId=240&tqId=2180959&ru=%2Fpractice%2Ff6b4770f453d4163acc419e3d19e6746&qru=%2Fta%2Fsql-advanced%2Fquestion-ranking&sourceUrl=

0 问题描述

从exam_record作答记录表中计算所有用户完成SQL类别高难度试卷得分的截断平均值(去掉一个最大值和一个最小值后的平均值)。

1 数据准备

sql 复制代码
drop table if exists examination_info;
CREATE TABLE  examination_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    exam_id int UNIQUE NOT NULL COMMENT '试卷ID',
    tag varchar(32) COMMENT '类别标签',
    difficulty varchar(8) COMMENT '难度',
    duration int NOT NULL COMMENT '时长',
    release_time datetime COMMENT '发布时间'
)CHARACTER SET utf8 COLLATE utf8_general_ci;

drop table if exists exam_record;
CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid int NOT NULL COMMENT '用户ID',
    exam_id int NOT NULL COMMENT '试卷ID',
    start_time datetime NOT NULL COMMENT '开始时间',
    submit_time datetime COMMENT '提交时间',
    score tinyint COMMENT '得分'
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
  (9001, 'SQL', 'hard', 60, '2020-01-01 10:00:00'),
  (9002, '算法', 'medium', 80, '2020-08-02 10:00:00');

INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2020-01-02 09:01:01', '2020-01-02 09:21:01', 80),
(1001, 9001, '2021-05-02 10:01:01', '2021-05-02 10:30:01', 81),
(1001, 9001, '2021-06-02 19:01:01', '2021-06-02 19:31:01', 84),
(1001, 9002, '2021-09-05 19:01:01', '2021-09-05 19:40:01', 89),
(1001, 9001, '2021-09-02 12:01:01', null, null),
(1001, 9002, '2021-09-01 12:01:01', null, null),
(1002, 9002, '2021-02-02 19:01:01', '2021-02-02 19:30:01', 87),
(1002, 9001, '2021-05-05 18:01:01', '2021-05-05 18:59:02', 90),
(1003, 9001, '2021-02-06 12:01:01', null, null),
(1003, 9001, '2021-09-07 10:01:01', '2021-09-07 10:31:01', 50);

2 数据分析

**方式一:**截断平均值:(总和-最大值-最小值) / (总个数-2) = (sum(score) - max(score) - min(score)) / (count(score) - 2)

sql 复制代码
select tag,
       difficulty,
       -- 平均值保留1位小数
       round((sum(score) - max(score) - min(score)) / (count(score) - 2), 1) as clip_avg_score
from exam_record er
join examination_info ei on er.exam_id = ei.exam_id
where ei.tag="SQL" and ei.difficulty="hard"

需要注意:

  • 聚合函数sum, max ,min 会自定忽略null值
  • 重复的最大值/最小值,该题只用去掉一个最大值/最小值就行,所以分母是count(socre) -2

方式二:开窗函数

sql 复制代码
select  tag,
        difficulty,
        round(avg(score), 1) as clip_avg_score
from(select  tag,
             difficulty,
             score,
             --开窗
             row_number() over(order by score asc) as rk_asc,
             row_number() over(order by score desc) as rk_desc
   from examination_info as i
   join exam_record as r
   on i.exam_id = r.exam_id
   where tag = 'SQL' and difficulty = 'hard' and score is not null) as tmp
where rk_asc <> 1 and rk_desc <> 1
group by tag, difficulty;

需要注意:

  • 窗口函数不像max()和min()会自动忽略null值,所以要在where子句提前把null值去掉。否则row_number也会对它们排序

3 小结

本案例中需要注意细节:除了 count(*)会计算null值,其余的聚合函数 sum(*), avg(*),max(*),min(*),count(1) 等中会自动忽略null值;但是开窗函数row_number() over、dense_rank() over、rank() over会对null进行计算。

相关推荐
Bdygsl9 分钟前
MySQL(6)—— 视图
数据库·mysql
oradh11 分钟前
数据库入门概述
数据库·oracle·数据库基础·数据库入门
BullSmall19 分钟前
一套定制化高级 payload 合集
数据库·安全性测试
zbdx不知名菜鸡33 分钟前
postgre sql 数据库查询优化
数据库·postgresql
9稳1 小时前
基于PLC的生产线自动升降机设计
开发语言·网络·数据库·嵌入式硬件·plc
四七伵1 小时前
Spring Boot项目中varchar字段为什么不用NULL?告别空指针从建表开始
数据库·后端
Mr.45671 小时前
JDK17+Druid+SpringBoot3+ShardingSphere5 多表分库分表完整实践(MySQL+PostgreSQL)
java·数据库·spring boot·mysql·postgresql
Elastic 中国社区官方博客1 小时前
使用 ES|QL 变量控件将仪表板转变为调查工具
大数据·运维·服务器·数据库·elasticsearch·搜索引擎·全文检索
feng68_1 小时前
Ansible还原数据库节点
linux·运维·数据库·ansible
乐hh1 小时前
清理MySQL数据
数据库·mysql