SQL,刷题总结(一) 常见的部门薪水类型问题

思路

该类题目往往都伴随着子查询排序的应用,个别题目伴随着NULL值的判断,以及其他的函数使用。

(注:以下题目类型以及部分解答思路均转自力扣(LeetCode),有需要的朋友可自行在力扣网上查找

单纯从薪水维度

  • 从最简单的维度出发进行发散——最高的薪水进行拓展

1.查询第二高的薪水

思路:
1.不在最高薪水里的最高薪水
2.按薪水降序排序,直接查询第二位

代码:
思路1

select max(salary) from 表  
where not in (子查询最高薪水)
复制代码

思路2

select (distinct salary) from 表 order by salary desc   
limit 1,1  

在需要判断NULL的情况下,添加ifnull函数
#select ifnull((select distinct Salary from 表
#	order by Salary desc
#	limit 1,1) ,null) as SecondHighestSalar
复制代码

(此处注意去重)

2.查询第N高的薪水

相对于第1题,思路1适用性变差
因而采用思路2:排序并查询
但该思路存在缺陷,适合全局查询,且不能在有重复值使用
思考自链接以及排序函数的方式

CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
    SET N := N-1;
  RETURN (
      select  salary from 表 order by salary desc   
      limit N,1
  );
END
复制代码
CREATE FUNCTION getNthHighestSalary(N INT) RETURNS INT
BEGIN
  RETURN (
        SELECT 
            DISTINCT salary
        FROM 
            (SELECT 
                salary, dense_rank() over(ORDER BY salary DESC) AS rnk
             FROM 
                employee) tmp
        WHERE rnk = N
  );
END
复制代码

从部门和薪水角度

  • 该类题目里,增加了一个维度,即要从部门来进行划分

部门工资最高的员工

该类型题目中增加了部门,那么就需要我们对group by或者where进行灵活运用
题目:leetcode-cn.com/problems/de…

RVA3KUQ32JCV57(YB4I~42P.png

则我们可以利用组where来查询(注意Join的方式,为什么不采用left join):

select 
    Department.Name as Department,
    Employee.Name as Employee,
    Salary
from Employee join Department on Department.Id = Employee.DepartmentId
where (Employee.DepartmentId,Salary) in 
        (select  
            DepartmentId,
            max(Salary)
            from Employee 
            group by DepartmentId
        )
复制代码

部门的前三高的所有员工

题目:leetcode-cn.com/problems/de…
该题思路与前一题相近,但有区别:
1.建立子查询
2.子查询里按组进行排序
3.直接筛选

部门三高.png

select 
    Department,
    Employee,
    Salary
from 
    (select 
        Department.Name as 'Department',
        Employee.name as 'Employee',
        Salary,
        dense_rank() over(partition by DepartmentId order by Salary desc ) as ranking
        from
        Employee inner join Department on Employee.DepartmentId = Department.Id
    )  as t
where ranking <= 3
复制代码

总结

这类题目,需要充分利用排序、分组的思路,切入的方向也非常重要,究竟是筛选掉高的,还是直接寻找低的;直接用where分组查询,还是用排序的方法,对待不同情况不能一概而论;自链接或者子查询思路上也各有长处。
最后以上题目均摘自力扣,同时力扣官网以及论坛都给出了不一样的解题思路。该处近摘取最贴近作者自己的思路解答,仅供参考。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享