• 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
    10005 94692 1
    10009 94409 2
    10010 94409 2
    10001 88958 3
    10007 88070 4
    10004 74057 5
    10002 72527 6
    10003 43311 7
    10006 43311 7
    10011 25828

    解题思路:

    其实求每个员工的当前薪水都比较容易,可以通过以下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;

  • 相关阅读:
    Java -- Map
    Bootstrap -- 标签属性
    SQLServer -- 竟然默认不区分大小写
    ThinkPHP -- 问题
    ThinkPHP
    MVC-内容详情页显示内容
    未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个依赖项。
    Random.Next获取随即数
    Razor语法小记
    VisualStudio自定义代码段_方法二
  • 原文地址:https://www.cnblogs.com/Transkai/p/13388416.html
Copyright © 2020-2023  润新知