本文共 1793 字,大约阅读时间需要 5 分钟。
第十五题要求我们按所有课程的平均成绩由高到低排列,输出学号、姓名、课程数、平均分以及各科成绩。以下是优化后的解决方案,考虑了代码的简化和性能优化。
方案步骤如下:
首先,我们需要准备基础数据:每个学生的总成绩和课程数。总成绩可以通过对score表中num字段求和得到,课程数则从course表中统计。
# 步骤一:计算每个学生的总成绩和课程数with base_data as ( select student_id 学号, sum(num) 总成绩, count(*) 课程数 from score group by student_id)
然后,对每个学生的总成绩除以课程数得到平均分。
# 步骤二:计算平均分with avg_data as ( select bd.*, avg(总成绩 / 课程数) 平均分 from base_data bd group by student_id)
接下来,我们按平均分降序排列学生数据。
# 步骤三:按平均分排序select student_id 学号, sname 姓名, 课程数, 平均分, round(平均分,1) 平均分保留一位小数from avg_dataorder by 平均分 desc;
为了得到每个学生的各科成绩,可以使用JOIN操作,连接score和course表:
# 步骤四:获取各科成绩select s student_id, group_concat(cs.cname,':',s.num order by cs.course_id) 各科成绩from score sjoin course cs on s.course_id = cs.course_idgroup by s.student_id;
将以上各步骤整合为一个完整的查询:
with base_data as ( select student_id 学号, sum(num) 总成绩, count(*) 课程数 from score group by student_id),avg_data as ( select bd.*, avg(总成绩 / 课程数) 平均分 from base_data bd group by student_id)select a.学生_id 学号, a.姓名, 课程数, avg_data.平均分 平均分, round(avg_data.平均分,1) 平均分保留一位小数, group_concat(cname,':',num order by course_id) 各科成绩from avg_data aleft join ( select student_id 学号, group_concat(cname,':',num order by course_id) 各科成绩 from score s join course cs on s.course_id = cs.course_id group by student_id) bon a.学生_id = b.学生_idorder by 平均分 desc;
group_concat中增加了order by course_id,确保了各科成绩的展示顺序一致。round函数保留一位小数,避免不必要的精度问题。这种优化后的解决方案不仅简化了复杂查询的步骤,同时提升了执行效率,适合处理大量数据的场景。
转载地址:http://ztrqz.baihongyu.com/