方案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窗口函数,以防数据中出现同一部门薪资相同的情况