SQL 求中位数

求中位数位置

背景:不考虑中位数是什么,只求中位数的位置

若为奇数,则中位数start位置=中位数end位置

若为偶数,则中位数end位置-中位数start位置=1

select job,floor((count(score)+1)/2) as start, floor((count(score)+2)/2) as end  from grade group by job order by job ;

求中位数

1.充分利用窗口函数

中位数条件分奇偶判断

select id,job,score,s_rank
from (
	select *, 
	(row_number()over(partition by job order by score desc))as s_rank, 
	(count(score)over(partition by job))as num 
from grade) t1
where t1.s_rank in (floor(t1.num/2)+1,if(mod(t1.num,2) = 0,floor(t1.num/2),floor(t1.num/2)+1)) order by id;

中位数条件由排序和总和计算

select id,job,score,s_rank
from (
	select *, 
	(row_number()over(partition by job order by score desc))as s_rank, 
	(count(score)over(partition by job))as num 
from grade) t1
where abs(t1.s_rank-(t1.num+1)/2)<1 order by id;

注意:不可在一次查询中对窗口函数的结果进行操作

2.中位数,正排倒排都是中位数

select id,job,score,rn2
from (
select *, 
(row_number()over(partition by job order by score ))as rn1,
(row_number()over(partition by job order by score desc))as rn2
 from grade ) as t1
where t1.rn1 = t1.rn2 or abs(t1.rn1 -t1.rn2) = 1 order by id;

报错:BIGINT UNSIGNED value is out of range

两种方式修改:

直接修改设置SET sql_mode='NO_UNSIGNED_SUBTRACTION'

或者修改代码

select id,job,score,rn2
from (
select *, 
(row_number()over(partition by job order by score ))as rn1,
(row_number()over(partition by job order by score desc))as rn2
 from grade ) as t1
where t1.rn1 = t1.rn2 or abs(cast(t1.rn1 as signed)-cast(t1.rn2 as signed)) = 1 order by id;

参考:SQL笔面试题:如何求取中位数?_数据森麟-CSDN博客

你可能感兴趣的:(SQL,学习笔记,sql,数据库,database)