SQL中GROUP BY 默认取非聚合的第一条记录
GROUP BY 分组中的坑
1.分组后select后的字段只能有以下两种:
- 出现在group by 后面的字段
- 使用聚合函数的列
2.group by 默认取非聚合的第一条记录
例题:牛客网数据库实战之获取所有部门中当前员工薪水最高的相关信息
表:dept_emp
表:salaries
错误的解题方法:
1 select e.dept_no,e.emp_no,max(salary) as maxSalary 2 from dept_emp e 3 inner join salaries s on e.emp_no = s.emp_no 4 group by dept_no 5 order by dept_no
其中e.emp_no既不是group by后面的字段,也不是使用聚合函数的列,emp_no是非聚合字段,不能出现在SELECT。因为一个聚合字段(dept_no)对应多个非聚合字段(emp_no),所以选择的时候,会默认选择非聚合字段中的第一个,于是出错。
显示错误的结果:
因为group by默认取非聚合的第一条记录,部门d004有两个员工,分别是1003,1004,由于select后面跟的emp_no既不是group by后面的字段,也不是使用聚合函数的列,因此默认选取了1003,而不是真实的数据1004!!!
正确的解题方法:
SELECT de.`dept_no`,de.`emp_no`,s.`salary` FROM dept_emp de JOIN salaries s ON de.`emp_no` = s.`emp_no` AND de.`to_date` = '9999-01-01' AND s.`to_date` = '9999-01-01' WHERE s.`salary`=( SELECT MAX(salary) FROM dept_emp de2 JOIN salaries s2 ON de2.`emp_no` = s2.`emp_no` AND de2.`to_date` = '9999-01-01' AND s2.`to_date` = '9999-01-01' WHERE de.`dept_no` =de2.`dept_no` GROUP BY de2.`dept_no` ) ORDER BY dept_no
注意: 关于为什么一定要两个表格的时间都限制成规定时间(9999-01-01)
因为薪水表是按年发的,而题目要查找的当前的薪水,所以要过滤掉以前的阶段。即一个领导从入职到现在阶段不同,薪水不同,所以to_date为最新,表示最新的薪水