LeetCode --- 569 员工薪水中位数

LeetCode --- 数据库(会员)
专栏:https://www.jianshu.com/nb/42460386

一、题目描述

来源:力扣(LeetCode)

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

+-----+------------+--------+
|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   |
+-----+------------+--------+

二、解题思路以及实现

解决中位数问题思路一定要清晰,首先是要对数据进行排序,增加一个自增列让薪资从低到高排序,然后取中间位置即可。基本可以应对大多数中位数问题。
注意几点:

  • @com变量用来判断是否与前一个变量相同,要放在IF判断之后
  • 关联统计每组总人数的表
  • 使用t.rn in (FLOOR(m.cnt/2 + 1),CEIL(m.cnt/2))来判断是否是中位数,则不需要去判断总数的奇偶数了
SELECT
        t.id,
        t.company,
        t.salary
    FROM
        (
        SELECT
            a.id,
            a.company,
            a.Salary,
        IF ( @com = a.company, @rn := @rn + 1, @rn := 1 ) AS rn,
            @com := a.company -- 必须放在后面
            
        FROM
            Employee a,
            ( SELECT @rn := 1, @com := NULL ) b 
        ORDER BY
            company,
            Salary 
        ) t 
    left join (SELECT company,count(*) as cnt from employee group by company) m
    on t.company = m.company
    where 
    t.rn in (FLOOR(m.cnt/2 + 1),CEIL(m.cnt/2))
若本题只有一个分组

则可以直接使用@rn来作为总人数,因为@rn从1开始,加到最后即为总人数

SELECT
        t.id,
        t.company,
        t.salary
    FROM
        (
        SELECT
            a.id,
            a.company,
            a.Salary,
        IF ( @com = a.company, @rn := @rn + 1, @rn := 1 ) AS rn,
            @com := a.company -- 必须放在后面
            
        FROM
            Employee a,
            ( SELECT @rn := 1, @com := NULL ) b 
        ORDER BY
            company,
            Salary 
        ) t 
    where 
    t.rn in (FLOOR(@rn/2 + 1),CEIL(@rn/2))

你可能感兴趣的:(LeetCode --- 569 员工薪水中位数)