多表查询中GROUP BY的正确用法?求解决SQL取部门最高薪资报错问题
问题描述
现有Employees和Department两张表,需要展示每个部门的最高薪资、对应员工姓名以及部门名称。
表数据
员工表(Employees)
EmpId | EmpName | salary | DeptId 101 | shubh1 | 1000 | 1 101 | shubh2 | 4000 | 1 102 | shubh3 | 3000 | 2 102 | shubh4 | 5000 | 2 103 | shubh5 | 12000 | 3 103 | shubh6 | 1000 | 3 104 | shubh7 | 1400 | 4 104 | shubh8 | 1000 | 4
部门表(Department)
DeptId | DeptName 1 | ComputerScience 2 | Mechanical 3 | Aeronautics 4 | Civil
尝试的SQL及报错
执行以下SQL语句:
SELECT DeptName FROM Department where deptid IN(select MAX(salary),empname,deptid FROM Employee GROUP By Employee.deptid)
出现报错:
Token error: 'Column 'Employee.EmpName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.' on server 4e0652f832fd executing on line 1 (code: 8120, state: 1, class: 16)
问题分析与解决
错误原因
你的SQL存在两处问题:
- GROUP BY语法违规:SQL标准要求,分组(GROUP BY)后的SELECT字段要么是分组字段,要么被聚合函数包裹。子查询中
EmpName既不在GROUP BY里,也没有被聚合函数处理,数据库无法确定返回分组下的哪个员工姓名,直接报错。 - IN子句格式错误:
deptid IN(...)要求子查询返回单字段结果,但你的子查询返回了3个字段,逻辑上不成立。
正确解法
方法1:子查询获取部门最高薪后关联
先查询每个部门的最高薪资,再关联员工表和部门表匹配对应记录:
SELECT d.DeptName, e.EmpName, e.salary AS MaxDeptSalary FROM Employees e JOIN Department d ON e.DeptId = d.DeptId JOIN (SELECT DeptId, MAX(salary) AS max_sal FROM Employees GROUP BY DeptId) m ON e.DeptId = m.DeptId AND e.salary = m.max_sal;
方法2:使用窗口函数(更简洁)
用RANK()窗口函数标记部门内薪资排名,再筛选出最高薪的员工:
WITH RankedEmployees AS ( SELECT EmpName, salary, DeptId, RANK() OVER(PARTITION BY DeptId ORDER BY salary DESC) AS salary_rank FROM Employees ) SELECT d.DeptName, re.EmpName, re.salary AS MaxDeptSalary FROM RankedEmployees re JOIN Department d ON re.DeptId = d.DeptId WHERE re.salary_rank = 1;
如果部门内有多个员工薪资同为最高,RANK()会保留所有符合条件的记录;若只需返回一条,可替换为ROW_NUMBER()。
内容的提问来源于stack exchange,提问作者shubham
相关产品推荐
相关产品推荐

