【sql】统计工资在部门前三的信息 Department Top Three Salaries

问题:

The Employee table holds all employees. Every employee has an Id, and there is also a column for the department Id.

+----+-------+--------+--------------+
| Id | Name  | Salary | DepartmentId |
+----+-------+--------+--------------+
| 1  | Joe   | 70000  | 1            |
| 2  | Henry | 80000  | 2            |
| 3  | Sam   | 60000  | 2            |
| 4  | Max   | 90000  | 1            |
| 5  | Janet | 69000  | 1            |
| 6  | Randy | 85000  | 1            |
+----+-------+--------+--------------+

The Department table holds all departments of the company.

+----+----------+
| Id | Name     |
+----+----------+
| 1  | IT       |
| 2  | Sales    |
+----+----------+

Write a SQL query to find employees who earn the top three salaries in each of the department. For the above tables, your SQL query should return the following rows.

+------------+----------+--------+
| Department | Employee | Salary |
+------------+----------+--------+
| IT         | Max      | 90000  |
| IT         | Randy    | 85000  |
| IT         | Joe      | 70000  |
| Sales      | Henry    | 80000  |
| Sales      | Sam      | 60000  |
+------------+----------+--------+

解决:

① 使用Select Count(Distinct),内交Employee和Department两张表,然后我们找出比当前薪水高的最多只能有两个,那么前三高的都能被取出来了。2360 ms

SELECT d.Name Department,e.Name Employee,e.Salary Salary
FROM Employee e JOIN Department d ON e.DepartmentId = d.Id
WHERE 
(SELECT COUNT(DISTINCT Salary) 
    FROM Employee 
    WHERE Salary > e.Salary AND DepartmentId = d.Id) < 3 
ORDER BY d.Name,e.Salary DESC;/*最多取出比当前值大的两个数值,按照部门名递增的顺序,工资递减的顺序排序*/

② 将上面方法中的<3换成了IN (0, 1, 2)。1608 ms

SELECT d.Name Department,e.Name Employee,e.Salary Salary
FROM Employee e,Department d
WHERE
(SELECT COUNT(DISTINCT Salary) FROM Employee
    WHERE Salary > e.Salary AND DepartmentId = d.Id) IN (0,1,2) 
AND e.DepartmentId = d.Id 
ORDER BY d.Name,e.Salary DESC;

③ 使用Group by Having Count(Distinct ..) 关键字。1353 ms。

SELECT d.Name Department,e.Name Employee,e.Salary Salary
FROM
(SELECT e1.Name,e1.Salary,e1.DepartmentId
    FROM Employee e1 JOIN Employee e2 ON e1.DepartmentId = e2.DepartmentId AND e1.Salary <= e2.Salary
    GROUP BY e1.Id
    HAVING COUNT(DISTINCT e2.Salary) <= 3) e
JOIN Department d ON e.DepartmentId = d.Id
ORDER BY d.Name,e.Salary DESC;/*使用自连接先取出前三个最大的工资,然后取出其所需要的内容*/

④ 给每个人都按照薪水的高低增加一个rank,最后返回rank值小于等于3的项即可。1671 ms

SELECT d.Name AS Department, e.Name AS Employee, e.Salary FROM 
(SELECT Name, Salary, DepartmentId,
@rank := IF(@pre_d = DepartmentId, @rank + (@pre_s <> Salary), 1) AS rank,
@pre_d := DepartmentId, @pre_s := Salary 
FROM Employee, (SELECT @pre_d := -1, @pre_s := -1, @rank := 1) AS init
ORDER BY DepartmentId, Salary DESC) e JOIN Department d ON e.DepartmentId = d.Id
WHERE e.rank <= 3 ORDER BY d.Name, e.Salary DESC;

转载于:https://my.oschina.net/liyurong/blog/1570852

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值