如果group by子句如何在mysql中获取中位数?

问题描述

我的MysqL版本是8。+。

表结构:

CREATE TABLE `loss` (
  `date` date DEFAULT NULL,`circle` varchar(100) DEFAULT NULL,`district` varchar(100) DEFAULT NULL,`kpi_1` int(11) DEFAULT NULL,`kpi_2` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

loss的数据:

insert  into `loss`(`date`,`circle`,`district`,`kpi_1`,`kpi_2`) values 
('2020-09-20','101','delhi',90,100),('2020-09-20','102','Punjab',80,10),'104',90),'New Delhi',20,45,23),4,13),7,150),40),50),NULL,NULL);

查询

select date,circle,district,count(*) as total_rows,sum(kpi_1),sum(kpi_2) from loss
group by date,distrcit

我可以获取所有总量,但是如何找到中位数呢?

解决方法

不幸的是,MySQL没有汇总的中位数函数或类似函数-甚至没有像MariaDB中那样作为窗口函数。

使用窗口功能的一种解决方法是:

select date,circle,district,count(*) cnt,sum(kpi_1) sum_kpi1,sum(kpi_2) sum_kpi2,avg(case when rn1 in (floor((cnt + 1)/2),floor((cnt + 2)/2)) then kpi1 end) media_kpi1,avg(case when rn2 in (floor((cnt + 1)/2),floor((cnt + 2)/2)) then kpi2 end) media_kpi2
from (
    select l.*,row_number() over(partition by date,district order by kpi1) rn1,district order by kpi2) rn2,count(*)     over(partition by date,district) cnt
    from loss
) l
group by date,district

这假定您要按日期,圆圈和地区汇总记录,如原始查询中所示。如果需要另一组列,则可以更改窗口函数的group by子句和partition s。