题解 | #最差是第几名(二)#
最差是第几名(二)
http://www.nowcoder.com/practice/165d88474d434597bcd2af8bf72b24f1
参考大佬的解法,把其中涉及的知识点简单陈述一下
1.with as (..) 其实就是子查询部分,其实没啥大用,主要是为了代码的可读性,相当于创建了一个临时表,后面用起来比较方便。
2.关于中位数的判定方法。此题的解法是分别求出 total , a(正序排列) ,b(逆序排列)。要注意total为奇偶时,判定条件略有不同,可以这样理解:
当total 为奇数时,if 某个数的正序排列位置 > total/2 且 某个数的逆序排列位置 > total/2 则该数为中位数。(举例 :total = 7 ,表中数据为1234567,按照题目要求,要输出的结果为4,其中4的正序位置为4,逆序位置也为4 ,4 > 7/2=3 ,所以成立。)
当total 为偶数时,if 某个数的正序排列位置 >= total/2 且 某个数的逆序排列位置 >= total/2 则该数为中位数。(举例 :total = 8 ,表中数据为12345678,按照题目要求,要输出的结果为4和5,其中4的正序位置为4,逆序位置也为5 ,4>= 8/2 且 5 >= 8/2;同理 数字5的正序位置为5 ,逆序位置为4 ,5>= 8/2 且 4 >= 8/2,所以成立)
题解中很多大佬的答案都没办法通过就是没有区分total 奇偶的情况。
3.主要是窗口函数的用法。窗口函数的用途:需要找到每组内排名等业务需求。通俗点理解就是可以在表上加一列你感兴趣的信息(排序、总和、平均值等)。基本语法:
<窗口函数> over ( paratition by <用于分组的列名>
order by <用于排序的列名> )
知识点介绍完毕,本题的代码如下:
with t_rank as
(
select grade,
(select sum(number) from class_grade) as total,
sum(number) over(order by grade) a,
sum(number) over(order by grade desc) b
from class_grade
order by grade
)
select grade
from t_rank
where (case when total % 2 == 1 then a> total /2 and b>total/2
else a>= total /2 and b>=total/2 end)
order by grade