气死我了少打一个括号debug半小时!!!

首先建新表存一下按等级顺序滚动累加的总人数,然后再加一列总人数方便之后使用。这里要说一下窗口函数可以不带任何参数直接空括号,这样就是对整个表进行聚合函数运算但又可以把结果加在每一列。

然后从原表中选出grade并限制grade要对应在中位数的grade。首先要注意,中位数可能是一个也可能是两个。通过ceil((n+1)/2),floor((n+1)/2)的方法算中位数若只有一个中位数两个值相等。这里我用的方法是选出滚动累加大于中位数的grade中最小的一个,通过两次判断分别对比ceil和floor以确保两个中位数都在。最后按grade排序。

with t AS
(select grade, sum(number) over (order by grade) as t_rank,
 sum(number) over () as cnt
from class_grade)

select c.grade from class_grade as c
where 
grade = (select t1.grade from (select t.grade, min(t.t_rank) from t 
                              where t.t_rank>=ceil((t.cnt+1)/2)) as t1) or
grade = (select t2.grade from (select t.grade, min(t.t_rank) from t 
                              where t.t_rank>=floor((t.cnt+1)/2)) as t2)
order by grade