Sql实战 1.单表复用进行比较排名

题目描述

对所有员工的当前(to_date='9999-01-01')薪水按照salary进行按照1-N的排名,相同salary并列且按照emp_no升序排列
CREATE TABLE `salaries` (
`emp_no` int(11) NOT NULL,
`salary` int(11) NOT NULL,
`from_date` date NOT NULL,
`to_date` date NOT NULL,
PRIMARY KEY (`emp_no`,`from_date`));

输出描述:

emp_nosalaryrank
10005946921
10009944092
10010944092
10001889583
10007880704
10004740575
10002725276
10003433117
10006433117
1001125828

解题思路:

其实求每个员工的当前薪水都比较容易,可以通过以下SQL来获取:
SELECT
    emp_no,
    salary
FROM
    salaries
WHERE
    to_date = '9999-01-01'
GROUP BY
    emp_no;
然后可以得到类似如下结果:
1
2
3
4
5
6
7
8
9
10
11
+--------+--------+
| emp_no | salary |
+--------+--------+
|  10001 |  88958 |
|  10002 |  72527 |
|  10003 |  43311 |
|  10004 |  74057 |
|  10005 |  94692 |
|  10006 |  43311 |
|  10007 |  88070 |
+--------+--------+
所以现在难点就是“如何按照salary进行按照1-N的排名”?
我想到的方案是对这个结果再次处理,比如构造两个上面结果这样的表,获取表2的 salary 大于等于表1 的 salary 的个数(因为同样 salary 算作一样的排名,所以需要去重处理),这样就得到了该员工的排名。也就是下面这个SQL:
SELECT
    result1.emp_no,
    result1.salary,
    COUNT(DISTINCT result2.salary) AS rank
FROM
    (
        SELECT
            emp_no,
            salary
        FROM
            salaries
        WHERE
            to_date = '9999-01-01'
        GROUP BY
            emp_no
    ) AS result1,
    (
        SELECT
            emp_no,
            salary
        FROM
            salaries
        WHERE
            to_date = '9999-01-01'
        GROUP BY
            emp_no
    ) AS result2
WHERE
    result2.salary >= result1.salary
GROUP BY
    result1.emp_no
ORDER BY
    result1.salary DESC,
    result1.emp_no ASC;
当然,这个SQL思路不变,写法还可以简化一下:
SELECT
    s1.emp_no,
    s1.salary,
    COUNT(DISTINCT s2.salary) AS rank
FROM
    salaries s1,
    salaries s2
WHERE
    s1.to_date = '9999-01-01'
AND s2.to_date = '9999-01-01'
AND s2.salary >= s1.salary
GROUP BY
    s1.emp_no
ORDER BY
    s1.salary DESC,
    s1.emp_no ASC;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值