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 |
+------------+----------+--------+
比184题复杂一点,求部门工资排名前三位的员工信息。
贴答案:
select d.Name Department,e1.Name Employee,e1.Salary Salary from
Employee e1,Department d where e1.DepartmentId = d.Id and 3 >
(select Count(Distinct e2.salary) from Employee e2 where e2.DepartmentId = d.Id and e2.Salary > e1.Salary)
Order BY d.Name,e1.salary desc
这道题关键在于前三位的理解,即忽略重复,(若有并排情况算作1位。)前三位有两种方法,一种用group by语句然后limit offset来显示所求。一种是直接查询,限定条件为比其薪水高的员工低于三个(不包含三个)。仍然用184题所使用的循环思想。e1.salary是改变着的,只要查出比他大的e2.salary的个数即可(并对e2.salary去重)如果误写成对e1.salary去重则限定条件无意义,因为对子查询来说,salary的个数永远是一个。
用group by 的解法
SELECT d.Name AS Department, e.Name AS Employee, e.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;解释:
Employee表自连接,限定条件e1.salary > e2.salary的目的是用数量表示排名,e1.salary<=e2.salary筛选出来的列在以e1.id分组求Count(DISTINCT e2.salary)筛选出的值就是前三名。最后在与部门表关联得出结果。