SQL求员工薪水中位数(困难)

Leetcode上的题目,记录一下。
原题连接:
https://leetcode-cn.com/problems/median-employee-salary/

+-----+------------+--------+
|Id   | Company    | Salary |
+-----+------------+--------+
|1    | A          | 2341   |
|2    | A          | 341    |
|3    | A          | 15     |
|4    | A          | 15314  |
|5    | A          | 451    |
|6    | A          | 513    |
|7    | B          | 15     |
|8    | B          | 13     |
|9    | B          | 1154   |
|10   | B          | 1345   |
|11   | B          | 1221   |
|12   | B          | 234    |
|13   | C          | 2345   |
|14   | C          | 2645   |
|15   | C          | 2645   |
|16   | C          | 2652   |
|17   | C          | 65     |
+-----+------------+--------+

题目:请编写SQL查询来查找每个公司的薪水中位数。挑战点:你是否可以在不使用任何内置的SQL函数的情况下解决此问题。

预期结果:

+-----+------------+--------+
|Id   | Company    | Salary |
+-----+------------+--------+
|5    | A          | 451    |
|6    | A          | 513    |
|12   | B          | 234    |
|9    | B          | 1154   |
|14   | C          | 2645   |
+-----+------------+--------+

本人初学者,可能写的东西没有很精简,望见谅。

具体思路是,先在原表中用over partition by 以公司为分组,对工资加序号。然后从选取序号为中位数的工资。

在这里我用了median1 和 median2两栏去表示中位数的两种情况。如果总数是偶数时(如6),那么median1是3,median2是4;如果总数是奇数时(如7),那么median1和median2都是4.

代码如下:

select t1.id,t1.company,t1.salary 
from 
(select id,company,salary, row_number() over (partition by company order by salary) rown, count(salary)     over (partition by company) ct
     from employee) t1
where
(t1.company,rown) in
    (select t.company, 
        (case when t.ct%2=0 then t.ct/2 else (t.ct+1)/2 end) median1
        -- (case when t.ct%2=0 then t.ct/2+1 else (t.ct+1)/2 end) median2 
    from 
        (select id,company,salary, 
        row_number() over (partition by company order by salary) rown, 
        count(salary) over (partition by company) ct
        from employee) t
    group by t.company)

or
(t1.company,rown) in
    (select t.company, 
        (case when t.ct%2=0 then t.ct/2+1 else (t.ct+1)/2 end) median2 
    from 
        (select id,company,salary, 
        row_number() over (partition by company order by salary) rown, 
        count(salary) over (partition by company) ct
        from employee) t
    group by t.company)

你可能感兴趣的:(SQL)