MySQL部门工资前三高的所有员工

「爱情、让人受尽委屈。」 2023-10-06 18:50 120阅读 0赞

MySQL部门工资前三高的所有员工

  • SQL架构
  • 题目描述
  • 题解
    • 方法:使用 JOIN 和子查询
    • 解题思路

SQL架构

  1. Create table If Not Exists Employee (Id int, Name varchar(255), Salary int, DepartmentId int);
  2. Create table If Not Exists Department (Id int, Name varchar(255));
  3. insert into Employee (Id, Name, Salary, DepartmentId) values ('1', 'Joe', '85000', '1');
  4. insert into Employee (Id, Name, Salary, DepartmentId) values ('2', 'Henry', '80000', '2');
  5. insert into Employee (Id, Name, Salary, DepartmentId) values ('3', 'Sam', '60000', '2');
  6. insert into Employee (Id, Name, Salary, DepartmentId) values ('4', 'Max', '90000', '1');
  7. insert into Employee (Id, Name, Salary, DepartmentId) values ('5', 'Janet', '69000', '1');
  8. insert into Employee (Id, Name, Salary, DepartmentId) values ('6', 'Randy', '85000', '1');
  9. insert into Employee (Id, Name, Salary, DepartmentId) values ('7', 'Will', '70000', '1');
  10. insert into Department (Id, Name) values ('1', 'IT');
  11. insert into Department (Id, Name) values ('2', 'Sales');

题目描述

Employee 表包含所有员工信息,每个员工有其对应的工号 Id,姓名 Name,工资 Salary 和部门编号 DepartmentId 。

  1. +----+-------+--------+--------------+
  2. | Id | Name | Salary | DepartmentId |
  3. +----+-------+--------+--------------+
  4. | 1 | Joe | 85000 | 1 |
  5. | 2 | Henry | 80000 | 2 |
  6. | 3 | Sam | 60000 | 2 |
  7. | 4 | Max | 90000 | 1 |
  8. | 5 | Janet | 69000 | 1 |
  9. | 6 | Randy | 85000 | 1 |
  10. | 7 | Will | 70000 | 1 |
  11. +----+-------+--------+--------------+
  12. Department 表包含公司所有部门的信息。
  13. +----+----------+
  14. | Id | Name |
  15. +----+----------+
  16. | 1 | IT |
  17. | 2 | Sales |
  18. +----+----------+
  19. 编写一个 SQL 查询,找出每个部门获得前三高工资的所有员工。例如,根据上述给定的表,查询结果应返回:
  20. +------------+----------+--------+
  21. | Department | Employee | Salary |
  22. +------------+----------+--------+
  23. | IT | Max | 90000 |
  24. | IT | Randy | 85000 |
  25. | IT | Joe | 85000 |
  26. | IT | Will | 70000 |
  27. | Sales | Henry | 80000 |
  28. | Sales | Sam | 60000 |
  29. +------------+----------+--------+

解释:

IT 部门中,Max 获得了最高的工资,Randy 和 Joe 都拿到了第二高的工资,Will 的工资排第三。销售部门(Sales)只有两名员工,Henry 的工资最高,Sam 的工资排第二。

题解

方法:使用 JOIN 和子查询

算法

公司里前 3 高的薪水意味着有不超过 3 个工资比这些值大。

  1. select e1.Name as 'Employee', e1.Salary
  2. from Employee e1
  3. where 3 >
  4. (
  5. select count(distinct e2.Salary)
  6. from Employee e2
  7. where e2.Salary > e1.Salary
  8. );

在这个代码里,我们统计了有多少人的工资比 e1.Salary 高,所以样例的输出应该如下所示。

  1. +----------+--------+
  2. | Employee | Salary |
  3. +----------+--------+
  4. | Joe | 85000 |
  5. | Henry | 80000 |
  6. | Max | 90000 |
  7. | Randy | 85000 |
  8. +----------+--------+
  9. 4 rows in set (0.00 sec)

然后,我们需要把表 Employee 和表 Department 连接来获得部门信息。

  1. SELECT
  2. d.Name AS 'Department', e1.Name AS 'Employee', e1.Salary
  3. FROM
  4. Employee e1
  5. JOIN
  6. Department d ON e1.DepartmentId = d.Id
  7. WHERE
  8. 3 > (SELECT
  9. COUNT(DISTINCT e2.Salary)
  10. FROM
  11. Employee e2
  12. WHERE
  13. e2.Salary > e1.Salary
  14. AND e1.DepartmentId = e2.DepartmentId
  15. );
  16. +------------+----------+--------+
  17. | Department | Employee | Salary |
  18. +------------+----------+--------+
  19. | IT | Joe | 85000 |
  20. | Sales | Henry | 80000 |
  21. | Sales | Sam | 60000 |
  22. | IT | Max | 90000 |
  23. | IT | Randy | 85000 |
  24. | IT | Will | 70000 |
  25. +------------+----------+--------+
  26. 6 rows in set (0.00 sec)
  27. SELECT
  28. Department.NAME AS Department,
  29. e1.NAME AS Employee,
  30. e1.Salary AS Salary
  31. FROM
  32. Employee AS e1,Department
  33. WHERE
  34. e1.DepartmentId = Department.Id
  35. AND 3 > (SELECT count( DISTINCT e2.Salary )
  36. FROM Employee AS e2
  37. WHERE e1.Salary < e2.Salary AND e1.DepartmentId = e2.DepartmentId )
  38. ORDER BY Department.NAME,Salary DESC;

解题思路

  1. select
  2. d.name as Department, e1.name as employee, e1.salary as salary
  3. from
  4. Department d
  5. join Employee e1 on d.id = e1.departmentid
  6. join Employee e2 on e1.departmentid = e2.departmentid and e1.salary<=e2.salary
  7. group by
  8. d.name, e1.name
  9. having
  10. count(distinct e2.salary)<=3
  11. order by
  12. d.name, e1.salary desc;
  13. +------------+----------+--------+
  14. | Department | employee | salary |
  15. +------------+----------+--------+
  16. | IT | Max | 90000 |
  17. | IT | Joe | 85000 |
  18. | IT | Randy | 85000 |
  19. | IT | Will | 70000 |
  20. | Sales | Henry | 80000 |
  21. | Sales | Sam | 60000 |
  22. +------------+----------+--------+
  23. 6 rows in set (0.00 sec)
  24. SELECT
  25. d.NAME department, t.NAME employee, salary
  26. FROM
  27. (
  28. SELECT *,
  29. @r := IF(@pD = departmentid, IF(@pS = salary, @r, @r + 1 ), 1 ) AS 'rank',
  30. @pD := departmentid,
  31. @pS := salary
  32. FROM
  33. Employee, ( SELECT @pS := NULL, @pD := NULL, @r := 0 ) init
  34. ORDER BY
  35. departmentid, salary DESC
  36. ) t
  37. JOIN Department d ON t.departmentid = d.id
  38. WHERE
  39. t.rank <=3;

发表评论

表情:
评论列表 (有 0 条评论,120人围观)

还没有评论,来说两句吧...

相关阅读