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