# 先查询各分数段最差的排名及其上一等级的最差排名(即得出各分数段涵盖人数的范围)----表(1) select grade, ifnull(lag(rank_l,1)over(order by rank_l),0) rank_f, rank_l from ( select grade, sum(`number`)over(order by grade) rank_l from class_grade ) k1 # 查询该成绩表的中位数位置,使用union保证当总数为奇数时去除相同位置----表(2) select case when sum(`number`)%2=0 then sum(`number`)/2 else (sum(`number`)+1)/2 end as loc, 'yes' as jurge from class_grade union select case when sum(`number`)%2=0 then sum(`number`)/2+1 else (sum(`number`)+1)/2 end as loc, 'yes' from class_grade # ---------------------------------------完整代码------------------------------------------------ # 使用连接条件连接表(1)和表(2)用以判断中位数位置是否在该分数等级内【要注意可能不同中位数位置在一个分数段内】 select distinct grade from ( # 先查询各分数段最差的排名及其上一等级的最差排名(即得出各分数段涵盖人数的范围)----表(1) select grade, ifnull(lag(rank_l,1)over(order by rank_l),0) rank_f, rank_l from ( select grade, sum(`number`)over(order by grade) rank_l from class_grade ) k1 ) t1 join ( # 查询该成绩表的中位数位置----表(2) select case when sum(`number`)%2=0 then sum(`number`)/2 else (sum(`number`)+1)/2 end as loc, 'yes' as jurge from class_grade union select case when sum(`number`)%2=0 then sum(`number`)/2+1 else (sum(`number`)+1)/2 end as loc, 'yes' from class_grade ) t2 on t2.loc > t1.rank_f and t2.loc <= t1.rank_l order by grade;
很笨的一个办法,没有用到评论区大佬说的“当某一数的正序和逆序累计均大于整个序列的数字个数的一半即为中位数”的规律。
主要思路是:(1)查询不同分数段的包含人数情况;(2)查询中位数的位置;(3)把上述两个表连接并使用连接条件判断中位数是否位于该分数段内,若位于则连接成功,也就能够最后输出该分数段。