1.数据准备和需求
数据准备:
create table employee ( id int auto_increment primary key comment '编号', company varchar(255) comment '公司', salary int comment '工资' ); insert into employee(id, company,salary) values (1,'A',2341); insert into employee(id, company,salary) values (2,'A',341); insert into employee(id, company,salary) values (3,'A',15); insert into employee(id, company,salary) values (4,'A',15314); insert into employee(id, company,salary) values (5,'A',451); insert into employee(id, company,salary) values (6,'A',513); insert into employee(id, company,salary) values (7,'B',15); insert into employee(id, company,salary) values (8,'B',13); insert into employee(id, company,salary) values (9,'B',1154); insert into employee(id, company,salary) values (10,'B',1345); insert into employee(id, company,salary) values (11,'B',1221); insert into employee(id, company,salary) values (12,'B',234); insert into employee(id, company,salary) values (13,'C',2345); insert into employee(id, company,salary) values (14,'C',2645); insert into employee(id, company,salary) values (15,'C',2645); insert into employee(id, company,salary) values (16,'C',2652); insert into employee(id, company,salary) values (17,'C',65);
计算每个公司工资的中位数,结果如下:
+----+---------+--------+ | id | company | salary | +----+---------+--------+ | 6 | A | 513 | | 5 | A | 451 | | 9 | B | 1154 | | 12 | B | 234 | | 14 | C | 2645 | +----+---------+--------+
2.结果实现
思路1:N为奇数,中位数排序编号是(N+1)/2;N为偶数,中位数排序编号是N/2和N/2+1,不管奇偶数就是(N+1)/2向下取整和(N+2)/2向下取整。
select id, company, salary from (select id, company, salary, cast(row_number() over (partition by company order by salary,id) as signed) asc_salary, count(1) over (partition by company) total_num from employee) t where asc_salary in ((total_num+1)/2,total_num/2,total_num/2+1) -- where asc_salary in (floor((total_num + 1)/2), floor((total_num + 2)/2)) ;
思路2:N为奇数,正序排序编号和逆序排序编号相等(相差0),N为偶数,正序排序编号和逆序排序编号互换(相差1);
select id, company, salary from (select id, company, salary, cast(row_number() over (partition by company order by salary,id) as signed) asc_salary, cast(row_number() over (partition by company order by salary desc,id desc) as signed) desc_salary from employee) t where asc_salary = desc_salary or abs(asc_salary-desc_salary) = 1;
思路3:不管奇数和偶数,正序排序编号、逆序排序编号大于等于N/2;
select id, company, salary from (select id, company, salary, cast(row_number() over (partition by company order by salary,id) as signed) asc_salary, cast(row_number() over (partition by company order by salary desc,id desc) as signed) desc_salary, count(1) over (partition by company) total_num from employee) t where asc_salary >= total_num/2 and desc_salary >= total_num/2;
思路4:不管数组长度是奇是偶,也不管元素是否唯一,中位数出现的频率一定大于等于 大于它的数与小于它的数的绝对值之差。
select min(id) id a.company, a.salary from employee as a, employee as b where a.company = b.company group by a.company, a.salary having sum(a.salary = b.salary) >= abs(sum(sign(a.salary - b.salary)))