SQL面试题更新 2026-08-05

在SQL中,如果要找出每个部门中工资最高的员工,应该如何编写查询语句?请给出具体的实现思路。

编码实现技术原理SQL

考察说明

考查SQL分组聚合与子查询/窗口函数的应用能力,以及处理并列最高值的边界情况。

回答思路

  1. 【回答框架 1】核心思路是先在部门内部比较工资,选出每个部门的最高工资,再关联员工表获取对应员工信息。常见实现有两种:一种是使用子查询,先按部门分组求出max(salary),然后用该结果与员工表内连接,连接条件是部门相同且工资等于该最高值;另一种是使用窗口函数row_number()或rank()按部门分区排序,但需要注意两者对并列名次的处理不同。
  2. 【回答框架 2】子查询写法更直观,适合面试快速作答:select e.* from emp e join (select dept_id, max(salary) as max_sal from emp group by dept_id) t on e.dept_id = t.dept_id and e.salary = t.max_sal。这种写法能保留每个部门所有工资等于最高值的员工记录,即可能返回多行。
  3. 【回答框架 3】窗口函数写法:select * from (select e.*, rank() over(partition by dept_id order by salary desc) as rn from emp e) t where rn = 1。rank()会为并列最高分配相同名次,从而保留并列员工;若要求每个部门只取一人,则应改用row_number()并附加处理并列的次级排序条件,如员工编号或入职时间。
  4. 【回答框架 4】实际应用中还需注意NULL值处理:若最高工资为NULL(即该部门所有员工工资均为NULL),上述两种写法都不会返回该部门记录,此时可用LEFT JOIN或IS NOT NULL显式排除。另外,若需同时展示部门名称,则需关联部门表,并注意字段命名冲突。
  5. 【关键点 1】先求每个部门的最高工资,再关联员工表筛选,是核心思路。
  6. 【关键点 2】子查询写法可保留所有并列最高工资的员工。
  7. 【关键点 3】窗口函数rank()保留并列,row_number()每个部门只取一行,需根据需求选择。
  8. 【关键点 4】若要求每个部门只返回一人,row_number()需补充次级排序条件。
  9. 【关键点 5】使用时注意NULL值处理,避免漏掉没有员工或工资为NULL的部门。
  10. 【易错点 1】不要只用group by直接查询非聚合列,如select dept_id, name, max(salary)会导致歧义,不同数据库行为不一致。
  11. 【易错点 2】注意窗口函数中rank()和row_number()对并列结果的处理差异,避免结果与预期不符。
  12. 【易错点 3】避免忽略分组后关联条件,需确保部门ID和工资同时匹配。