Leetcode刷题记之员工薪水中位数

查找每个公司的员工薪水中位数

题目来源:Leetcode

Employee表包括所有员工。包含三列:员工Id, 公司名和薪水

在这里插入图片描述
思路: 如果是奇数长度,那么 大于中位数的个数 = 小于中位数的个数

解答:(解题思路来自leetcode评论)

SELECT a.Id, a.Company, a.Salary
FROM 
	Employee a,
	Employee b
WHERE a.Company = b.Company
GROUP BY a.Company, a.Salary
HAVING SUM(CASE WHEN a.Salary = b.Salary THEN 1 ELSE 0 END) >= ABS(SUM(SIGN(a.Salary - b.Salary)))
ORDER BY a.Id

难点:

SUM(CASE WHEN a.Salary = b.Salary THEN 1 ELSE 0 END) >= ABS(SUM(SIGN(a.Salary - b.Salary)))

解析:
在自连中,a表salary与b表salary相等时为1。即计算a.Salary = b.Salary的个数

SUM(CASE WHEN a.Salary = b.Salary THEN 1 ELSE 0 END)

SIGN(): 正数取1,负数取-1,0取0

ABS(SUM(SIGN(a.Salary - b.Salary)))

即,
a.Salary > b.Salary --> 1
a.Salary < b.Salary --> -1
a.Salary = b.Salary --> 0

太抽象了,举个栗子:
假设有两组数:奇数列 1,2,3,4,5;偶数列1,2,3,4

① 从小到大排序,1排第一位。
1 = 1 --> 0; 1 < 2 --> -1; 1 < 3 --> -1; 1 < 4 --> -1; 1 < 5 --> -1
奇数:Abs(sum(0-1-1-1-1)) = 4
偶数:Abs(sum(0-1-1-1)) = 3
② 从小到大排序,2排第二位。
2 > 1 --> 1; 2 = 2 --> 0; 2 < 3 --> -1; 2 < 4 --> -1; 2 < 5 --> -1
奇数:Abs(sum(1+0-1-1-1)) = 2
偶数:Abs(sum(1+0-1-1)) = 1
③ 从小到大排序,3排第三位。(我们要找的中位数)
3 > 1 --> 1; 3 > 2 --> 1; 3 = 3 --> 0; 3 < 4 --> -1; 3 < 5 --> -1
奇数:Abs(sum(1+1-0-1-1)) = 0
偶数:Abs(sum(1+1-0-1)) = 1
④ 从小到大排序,4排第四位。
4 > 1 --> 1; 4 > 2 --> 1; 4 > 3 --> 1; 4 = 4 --> 0; 4 < 5 --> -1
奇数:Abs(sum(1+1+1+0-1)) = 2
偶数:Abs(sum(1+1+1+0)) = 3
⑤ 从小到大排序,5排第五位。
5 > 1 --> 1; 5 > 2 --> 1; 5 > 3 --> 1; 5 > 4 --> 1; 5 = 5 --> 0
奇数:Abs(sum(1+1+1+1+0)) = 4

发现什么规律了吗?

ABS(SUM(SIGN(a.Salary - b.Salary)))

这个计算值,我们可以当成是衡量偏移中间位置的一个程度。越靠近中间位置,得到的数值越小。对于个数为奇数的数组,中位数的偏移值为0。因为大于中位数和小于中位数的个数相等,能够相互抵消。而个数为偶数的数组,中位数的偏移值为1,因为不能够完全抵消。

即,中位数的 ABS(SUM(SIGN(a.Salary - b.Salary))) <= 1
这里可以用SUM(CASE WHEN a.Salary = b.Salary THEN 1 ELSE 0 END)进行限制

在这里插入图片描述
得到结果:
在这里插入图片描述
优化:中位数取平均值。

欢迎指正!( ᖛ ̫ ᖛ )ʃ)
Good Good Study
Day Day No Hair
与大家共勉!

发布了11 篇原创文章 · 获赞 0 · 访问量 237

猜你喜欢

转载自blog.csdn.net/weixin_44900533/article/details/105536589