You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

执行GROUP BY查询各部门最高薪员工时为何触发ERROR 1055?

解析MySQL ERROR 1055: GROUP BY与ONLY_FULL_GROUP_BY模式冲突的原因

先明确你的场景:
你有一个employees表,结构和数据如下:

表结构

CREATE TABLE employees(id int AUTO_INCREMENT PRIMARY KEY, emp_name VARCHAR(10), dept VARCHAR(10), salary DECIMAL(8,2));

插入数据

INSERT INTO employees (dept,emp_name,salary) VALUES('Engg','Sam',1000);
INSERT INTO employees (dept,emp_name,salary) VALUES('Engg','Smith',2000);
INSERT INTO employees (dept,emp_name,salary) VALUES('HR','Denis',1500);
INSERT INTO employees (dept,emp_name,salary) VALUES('HR','Danny',3000);
INSERT INTO employees (dept,emp_name,salary) VALUES('IT','David',2000);
INSERT INTO employees (dept,emp_name,salary) VALUES('IT','John',3000);
INSERT INTO employees (dept,emp_name,salary) VALUES('Sales','Ravi',4000);
INSERT INTO employees (dept,emp_name,salary) VALUES('Sales','Bob',6000);
INSERT INTO employees (dept,emp_name,salary) VALUES('HR','Rick',4500);
INSERT INTO employees (dept,emp_name,salary) VALUES('IT','Mathew',2500);

表数据

+----+----------+-------+---------+
| id | emp_name | dept  | salary  |
+----+----------+-------+---------+
| 1  | Sam      | Engg  | 1000.00 |
| 2  | Smith    | Engg  | 2000.00 |
| 3  | Denis    | HR    | 1500.00 |
| 4  | Danny    | HR    | 3000.00 |
| 5  | David    | IT    | 2000.00 |
| 6  | John     | IT    | 3000.00 |
| 7  | Ravi     | Sales | 4000.00 |
| 8  | Bob      | Sales | 6000.00 |
| 9  | Rick     | HR    | 4500.00 |
| 10 | Mathew   | IT    | 2500.00 |
+----+----------+-------+---------+

你执行了这条SQL想查询各部门薪资最高的员工:

SELECT id, emp_name, salary, dept FROM employees GROUP BY dept;

结果触发了错误:

ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test_db.employees.ID' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by


错误原因详解

这个错误的核心是MySQL的only_full_group_by SQL模式在严格约束你的查询逻辑,它是SQL标准规定的行为,MySQL从5.7版本开始默认启用了这个模式。

1. only_full_group_by的核心规则

简单来说,这个模式要求:

  • SELECT列表里的每一列,要么是GROUP BY子句中明确列出的列,要么是被聚合函数(比如MAX()、MIN()、COUNT())包裹的列
  • 唯一例外:如果GROUP BY的列是表的主键(或唯一键,能唯一标识每一行),那么SELECT里的其他列可以不用在GROUP BY里——因为主键确定后,其他列的值也就唯一确定了,属于功能依赖关系。

2. 你的SQL直接违反了规则

看你的查询:SELECT id, emp_name, salary, dept FROM employees GROUP BY dept;

  • GROUP BY的只有dept列,但dept不是唯一键(每个部门对应多个员工)
  • SELECT里的id、emp_name、salary既不在GROUP BY里,也没有用聚合函数包裹

举个具体例子:HR部门有3个员工,他们的id分别是3、4、9,薪资分别是1500、3000、4500。当你按dept分组后,MySQL根本不知道要返回这三个员工中的哪一个的id、姓名和薪资——这种模糊的查询在严格模式下是不被允许的,所以直接抛出了错误。


实现需求的正确写法

你真正的需求是查询各部门中薪资最高的员工,可以用以下两种方式实现:

方法1:子查询关联(兼容所有MySQL版本)

先找出每个部门的最高薪资,再关联原表找到对应的员工:

SELECT e.id, e.emp_name, e.salary, e.dept
FROM employees e
INNER JOIN (
    -- 子查询获取各部门最高薪资
    SELECT dept, MAX(salary) AS max_salary
    FROM employees
    GROUP BY dept
) dept_max ON e.dept = dept_max.dept AND e.salary = dept_max.max_salary;

方法2:窗口函数(MySQL 8.0及以上版本推荐)

用RANK()窗口函数给每个部门的员工按薪资降序排名,然后取排名为1的员工:

SELECT id, emp_name, salary, dept
FROM (
    SELECT *,
           -- 按部门分区,薪资降序排名
           RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS salary_rank
    FROM employees
) ranked_emps
WHERE salary_rank = 1;

这两种写法都能正确返回各部门薪资最高的员工,同时符合only_full_group_by的规则。


内容的提问来源于stack exchange,提问作者Manikandan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:16:26