SQL12题解:获取所有部门中当前员工薪水最高的相关信息

获取每个部门中当前员工薪水最高的相关信息

http://www.nowcoder.com/questionTerminal/4a052e3e1df5435880d4353eb18a91c6

方案1:采用MAX函数求出最高薪资

  • 解题思路:
    first:求出每个部门的最高薪资集合,作为临时表t
    second:联结dept_emp,salaries表,采用内连接(其实外连接也可以,如果数据设计合理内外连接结果都一样),这里的目的是为了后面可以同时对应展现dept_no和emp_no
    third:将第二步的语句联结第一步的临时表t,联结条件为dept_no,同时采用WHERE语句使salary = t.maxsal

第一步:求出每个部门员工的最高薪资,作为临时表t

    SELECT d.dept_no,MAX(s.salary) AS maxsal
    FROM dept_emp d
    INNER JOIN salaries s
    ON d.emp_no = s.emp_no
    GROUP BY d.dept_no;

误区:使用GROUP BY子句后,select 语句中只能出现group by语句中出现的字段,或者聚合函数,所以这里无法同时出现dept_no,emp_no.
(mysql语法松散,允许出现select语句中出现group by语句未出现的字段,但这样展示没有意义,因为记录并没有对应

第二步:因为题目要求检索到emp_no,所以先联结dept_emp,salaries表
题目要求展现的字段

SELECT d1.emp_no,s1.salary AS maxSalary
    FROM dept_emp d1 
    INNER JOIN salaries s1 
    ON d1.emp_no = s1.emp_no

第三步:将第二步的语句联结第一步所形成的临时表t,使用where语句限定salary = t.salary

SELECT t.dept_no,d1.emp_no,s1.salary AS maxSalary
    FROM dept_emp d1 INNER JOIN salaries s1 
    ON d1.emp_no = s1.emp_no
    INNER JOIN (SELECT d.dept_no,MAX(s.salary) AS maxsal
            FROM dept_emp d
            INNER JOIN salaries s
                    ON d.emp_no = s.emp_no
                    GROUP BY d.dept_no
                ) t
    ON d1.dept_no = t.dept_no
    WHERE s1.salary = t.maxsal
    ORDER BY t.dept_no;

补充:有同学可能会觉得联结三个表太麻烦了,这里也可以采用联结两个表dept_emp,salaries的方式,然后临时表t作为where子句中的子查询,将第一步临时表t中获得的dept_no及其最高薪水maxsal作为子查询的条件以元组的形式出现。具体代码如下:

SELECT d.dept_no,d.emp_no,s.salary AS maxSalary
    FROM dept_emp d
    INNER JOIN salaries s
    ON d.emp_no = s.emp_no
    WHERE (d.dept_no,s.salary) 
        IN (SELECT d.dept_no,MAX(s.salary) AS maxsal
            FROM dept_emp d
                    INNER JOIN salaries s
            ON d.emp_no = s.emp_no
            GROUP BY d.dept_no)
    ORDER BY d.dept_no ASC;

方案2:采用RANK窗口函数分部门按薪资倒序排序,选择排在第一位的记录

第一步:联结dept_emp,salaries表,分部门按薪资倒序排序

SELECT d.dept_no,d.emp_no,s.salary,DENSE_RANK() OVER (PARTITION BY d.dept_no ORDER BY s.salary DESC) AS sal_rank
    FROM dept_emp d 
    INNER JOIN salaries s 
    ON d.emp_no = s.emp_no;

第二步:选择展示

SELECT t.dept_no,t.emp_no,t.salary AS maxSalary 
    FROM (SELECT d.dept_no,d.emp_no,s.salary,DENSE_RANK() OVER (PARTITION BY d.dept_no ORDER BY s.salary DESC) AS sal_rank
            FROM dept_emp d 
            INNER JOIN salaries s 
            ON d.emp_no = s.emp_no) t
    WHERE t.sal_rank = 1
    ORDER BY t.dept_no;

这里使用DENSE_RANK窗口函数,以防数据中出现同一部门薪资相同的情况

全部评论
我觉得rank和dense_rank都可以,rank和dense_rank的区别在于并列会导致后续排名不连续,但这里只要最高的,所以没有区别
9 回复 分享
发布于 2021-08-08 13:08
Denserank 并不能解决多个最高分的情况,而应该用rowNumber
4 回复 分享
发布于 2021-09-07 21:44
为什么窗口函数不可以用 MAX(salary)啊? 下面这个就行不通 select d.dept_no ,d.emp_no ,Salary ,max(salary)over(partition by dept_no order by dept_no) from dept_emp d , salaries s where d.emp_no = s.emp_no and d.to_date = '9999_01_01' ;
3 回复 分享
发布于 2022-06-24 18:55
窗口函数真的是简单好多,而且感觉窗口函数就是为了解决这一类问题封装的; 然后楼主的第一种方法最大值那种, 主题思路是通过构造辅助列(部门最高薪资)--可以简单的就是“T表”一步到位,然后只剩嵌套取值就行了,这种方法的问题就是 存在并列多个人MAX(薪资)相同;
3 回复 分享
发布于 2022-03-01 20:40
谢谢!
2 回复 分享
发布于 2021-05-12 01:08
好好好,漂亮的答案
1 回复 分享
发布于 2024-01-28 14:32 辽宁
为啥小写就不行啊
1 回复 分享
发布于 2023-06-19 16:57 河北
还是窗口函数简洁明了
点赞 回复 分享
发布于 2024-02-21 11:44 四川
我第一反应也是用窗口函数,但是还没熟悉,就先出来两个表的方法了。后面补充了窗口函数的方式。 select de2.dept_no,de2.emp_no,de2.salary from( select de.dept_no,de.emp_no,salary,rank()over(partition by de.dept_no order by salary desc) rank from dept_emp de left join salaries sa on de.emp_no = sa.emp_no where de.to_date = '9999-01-01' and sa.to_date='9999-01-01') de2 where de2.rank=1 order by de2.dept_no
点赞 回复 分享
发布于 2021-12-09 11:56

相关推荐

评论
126
21
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务