1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column '207zh_demo.employees.employee_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
时间: 2025-04-23 20:37:49 浏览: 38
<think>嗯,用户遇到了MySQL的1055错误,这个错误和sql_mode中的only_full_group_by有关。我需要先理解这个错误的原因。根据引用中的内容,这个错误通常发生在SELECT列表中的列没有在GROUP BY子句中,并且这些列不是聚合函数的一部分,导致MySQL无法确定如何显示这些非聚合列的值。
首先,我要确定用户使用的MySQL版本。因为从5.7版本开始,默认启用了ONLY_FULL_GROUP_BY模式,这会导致更严格的GROUP BY检查。用户可能是在升级到5.7或更高版本后遇到了这个问题。
接下来,解决方案大概分为几个方向:修改SQL查询语句使其符合ONLY_FULL_GROUP_BY的要求,或者调整sql_mode设置来禁用这个模式。不过,用户可能更倾向于不修改现有查询,所以可能需要调整配置。但需要注意的是,禁用严格模式可能会影响数据的正确性,所以需要权衡。
对于方法一,修改查询语句。需要确保SELECT列表中的所有列要么在GROUP BY中,要么被聚合函数包裹。比如,如果有多个非聚合列,可能需要使用ANY_VALUE()函数,或者检查是否有必要将这些列加入GROUP BY。例如,如果用户有一个GROUP BY category的查询,但SELECT了id和category,那么id可能需要用MAX(id)或者ANY_VALUE(id)来处理。
方法二是临时修改sql_mode。通过SET命令在当前会话中修改,这样不会影响其他连接。但用户可能希望永久生效,所以需要修改配置文件my.cnf或my.ini,添加sql_mode的设置,去掉ONLY_FULL_GROUP_BY。需要提醒用户重启MySQL服务才能使配置生效。
方法三使用ANY_VALUE()函数,这是MySQL提供的解决方案,允许非聚合列存在,但需要用户修改查询。这可能适用于那些无法改变GROUP BY结构但又需要快速修复的情况。
另外,用户可能需要了解为什么会出现这个问题,比如GROUP BY的不正确使用导致数据歧义。比如,同一个分组中有多个不同的非聚合列值,MySQL无法确定应该选哪个,所以严格模式禁止这种情况。这时候,正确的做法应该是调整查询逻辑,确保数据的一致性。
可能还需要检查现有的SQL语句,是否有不必要的列被选中,或者是否需要调整GROUP BY的字段。例如,如果用户按部门分组,但同时选择了员工姓名,这时候可能需要使用聚合函数或者调整分组条件。
另外,用户可能在生产环境中无法轻易修改配置,这时候临时解决方案可能更适用。但长期来看,调整查询语句更符合规范,避免潜在的数据问题。
最后,需要总结这些方法,并建议用户根据具体情况选择最适合的方案。如果是新系统,建议遵循ONLY_FULL_GROUP_BY的要求,保证查询的正确性;如果是旧系统迁移,可能需要暂时禁用该模式,并逐步调整查询语句。</think>### MySQL sql_mode=only_full_group_by 报错1055解决方案
#### 问题原因分析
当MySQL的$sql\_mode$包含$ONLY\_FULL\_GROUP\_BY$时,要求`GROUP BY`子句必须包含所有`SELECT`列表中的非聚合列[^1][^2]。例如以下查询:
```sql
SELECT department, employee_name, SUM(salary) FROM employees GROUP BY department;
```
会因$employee\_name$未出现在`GROUP BY`或聚合函数中而报错[^4]。
---
#### 解决方案分步说明
##### 方法一:修改查询语句(推荐)
**步骤1:添加缺失的GROUP BY列**
```sql
SELECT department, employee_name, SUM(salary)
FROM employees
GROUP BY department, employee_name; -- 明确分组依据
```
**步骤2:使用聚合函数包裹非分组列**
```sql
SELECT department, MAX(employee_name), SUM(salary)
FROM employees
GROUP BY department; -- 取最大员工名
```
##### 方法二:调整sql_mode配置
**临时修改(会话级)**
```sql
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
```
**永久修改(需重启MySQL)**
1. 修改配置文件`my.cnf`或`my.ini`:
```ini
[mysqld]
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
```
2. 重启MySQL服务
##### 方法三:使用ANY_VALUE()函数(MySQL 5.7+)
```sql
SELECT department, ANY_VALUE(employee_name), SUM(salary)
FROM employees
GROUP BY department; -- 显式声明接受任意值[^5]
```
---
#### 各方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|------|------|------|----------|
| 修改查询 | 符合SQL标准,数据准确性高 | 需重构现有SQL | 新系统开发 |
| 调整sql_mode | 快速生效 | 可能引发数据歧义 | 旧系统迁移 |
| ANY_VALUE() | 平衡灵活性与规范性 | 需MySQL 5.7+ | 部分列无需精确分组 |
---
阅读全文
相关推荐
















