MySQL报错#1140:不使用GROUP BY查询最低薪资员工如何解决?
不使用GROUP BY查询最低薪资员工的报错解决方案
报错原因
你触发的1140报错是因为MySQL默认开启了only_full_group_by SQL模式,该模式的校验规则为:在包含聚合函数(MIN()/MAX()/SUM()等)的查询中,SELECT列表里的非聚合字段必须全部出现在GROUP BY子句中,否则数据库无法确定非聚合字段要返回哪一行的数据。你的查询用了MIN(salary)聚合函数,但name_surname是非聚合字段,且未声明GROUP BY,因此触发校验失败。
无需GROUP BY的解决方案
推荐通过子查询先拿到全局最低薪资,再关联匹配对应的员工信息,该写法完全符合SQL规范,不需要用到GROUP BY,且能正确返回所有薪资为最低值的员工:
SELECT c.salary AS min_salary, p.name_surname FROM player p INNER JOIN contracts c ON p.id = c.id WHERE c.salary = (SELECT MIN(salary) FROM contracts) LIMIT 0, 50
方案说明
- 子查询
SELECT MIN(salary) FROM contracts单独计算全局最低薪资,不需要关联其他表,执行效率高 - 外层查询关联员工表和合同表,筛选出所有薪资等于最低值的员工,存在多名最低薪资员工时会全部返回
- 用显式INNER JOIN代替原来的隐式连接写法,SQL可读性和可维护性更强
不推荐的临时绕过方案
如果仅要临时绕过报错不调整逻辑,可以临时关闭当前会话的only_full_group_by模式,但该写法会随机返回某一个员工的姓名,无法保证拿到所有最低薪资员工,因此不建议生产环境使用:
-- 临时关闭当前会话的only_full_group_by模式 SET SESSION sql_mode = REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''); -- 执行你的原有查询 SELECT MIN(salary) as 'min_salary', name_surname FROM player, contracts WHERE player.id = contracts.id LIMIT 0, 50
内容的提问来源于stack exchange,提问作者Otabek
相关产品推荐
相关产品推荐

