这道题还是比较折磨人的,题目里说明当总人数是偶数时,要取出两个人,譬如12个人,那么就要取出6号和7号,如果13个人,只需要取出7号,我一开始就把中位数分两种情况考虑。于是我就这样子被绕了40分钟解决不了,提交代码后更是一直被4/6用例折磨

随着肚子饿了,终于灵光一闪,唉呀妈呀这中位数不就是总人数除以2就可以了嘛,
直接上最终思路如下:
按照题目,有4组成绩 A B C D,人数如下:
A   2
B  4
C  4
D  2
那么最差成绩排名如下:
A  2
B  6
C  10
D  12
注意中位数就是 12 / 2 = 6 这时候就构造一个字段,表示每组成绩的区间
A  null       2
B  2          6
C  6         10  
D  10       12
只要中位数6 在区间里即可,上表就是B、C都可以。
再来看看万恶的4/6例到底是什么。人数如下:
A    2
D    1
C    2
B    2
那么最差成绩排名如下:
A    2
B    4
C    6   
D    7
这个中位数是3.5!!!!不是4,而是3.5!!!再来找区间:
A  null       2
B  2          4
C  4         6 
D  6         7
很明显,符合中位数3.5的区间只有B!!!如果用中位数是4来算的话,结果是B、C,无法通过审查

代码如下:
#第一步:统计各组成绩最差的名次,以及总人数(为下一步求中位数打基础)
SELECT grade, SUM(number) over(ORDER BY grade) "t_rank" , 
    SUM(number) over()  "cnt"
FROM class_grade




#第二步:非常关键的一步,首先找出中位数(总人数/2即可,保留一位小数!),然后用窗口函数lag找出上一条记录,构造出封闭区间
SELECT grade, lag(t_rank,1) over(ORDER BY grade) "before_t_rank", t_rank,    
    ROUND(cnt / 2,1) "mid_num"
FROM
    (SELECT grade, SUM(number) over(ORDER BY grade) "t_rank" , 
        SUM(number) over() "cnt" 
    FROM class_grade) t

    
    
#第三步:找出中位数所在的区间的grade即可
SELECT grade
FROM
    (SELECT grade, lag(t_rank,1) over(ORDER BY grade) "before_t_rank", t_rank,    
        ROUND(cnt / 2,1) "mid_num"
    FROM
        (SELECT grade, SUM(number) over(ORDER BY grade) "t_rank" , 
            SUM(number) over() "cnt" 
        FROM class_grade) t) tt
WHERE  mid_num BETWEEN before_t_rank AND t_rank
end~