今天要解的题目是👉:185. Department Top Three Salaries(部门工资排前三的员工)

这题考察的知识点👉:两表连接JOIN的使用以及子查询

此题思路一👉:既然要查部门工资排前三,那么我们要知道有哪些部门?这里就要使用JOIN连接两表得到各个部门信息,然后再在各部门中排列出工资排前三的员工信息,这里就要用到子查询建立一个新表来跟原始表进行对比。(这也是官方的解法思路)

思路二👉: 还是要新建一个临时表后三表连接,查询条件是部门id一致并且原始工资表的工资要小于临时表的工资;接着既然是各部门,那么就用分组函数GROUP BY注意这里分组的条件是临时表的工资数量去重后要小于等于3;最后就是降幂排序ORDER BY

思路三👉(个人觉得最好理解,但是Leetcode上面运行不了。。。):就是使用窗口函数的DENSE_RANK(),适合有并列排名的表格,可以直接用部门id来分组,然后工资排序后生成新的排名列,接着JOIN连接两表,查询条件是排名小于等于3的即可!

下面依次看解法,首先是官方的解法一👇:

SELECT
    d.Name AS 'Department', e1.Name AS 'Employee', e1.Salary
FROM
    Employee e1
        JOIN
    Department d ON e1.DepartmentId = d.Id
WHERE
    3 > (SELECT
            COUNT(DISTINCT e2.Salary)
        FROM
            Employee e2
        WHERE
            e2.Salary > e1.Salary
                AND e1.DepartmentId = e2.DepartmentId
        )
;

再看解法二👇

SELECT D.Name AS Department, E.Name AS Employee, E.Salary 
FROM Department D, Employee E, Employee E2  
WHERE D.ID = E.DepartmentId AND E.DepartmentId = E2.DepartmentId AND
E.Salary <= E2.Salary
GROUP BY  D.ID,E.Name HAVING COUNT(DISTINCT E2.Salary) <= 3
ORDER BY  D.Name, E.Salary DESC;

最后看解法三👉(在本地MySQL版本为8.0.15,然后用窗口函数可运行出来)

SELECT D.Name AS Department, A.Name AS Employee, A.Salary 
FROM(
SELECT *, DENSE_RANK() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC)AS Num 
FROM Employee)A 
JOIN Department D ON A.DepartmentId = D.Id WHERE A.Num <= 3 AND A.Name IS NOT NULL;


再次提问各位知道Leetcode上面为啥MySQL用不了窗口函数吗?请知道的朋友告知一下,谢谢。

最后比较前面两种解法的效率,解法二更优