mysql5.7 遇见Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre的问题

本文介绍MySQL5.7中使用Group By时遇到的ONLY_FULL_GROUP_BY模式问题及解决方案,包括调整sql_mode设置的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql5.7在使用group by子句时,会遇到如下问题

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'ipm.cm.meas_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

这是由于违背了mysql5.7以后默认配置的sql_mode=only_full_group_by模式

如果启用了ONLY_FULL_GROUP_BY SQL模式(默认情况下),MySQL将拒绝选择列表,HAVING条件或ORDER BY列表的查询引用在GROUP BY子句中既未命名的非集合列,也不在功能上依赖于它们。(5.7.5之前,MySQL没有检测到功能依赖关系,默认情况下不启用ONLY_FULL_GROUP_BY。有关5.7.5之前的行为的说明,请参见“MySQL 5.6参考手册”。)

MySQL扩展到标准SQL允许在have子句中引用select列表中的别名表达式。在MySQL 5.7.5之前,enablingONLY_FULL_GROUP_BY禁用此扩展,因此需要使用unaliated表达式编写have子句。从MySQL 5.7.5开始,这个限制被取消,使得have子句可以引用别名,而不管是否启用了ONLY_FULL_GROUP_BY。

 

有关额外的讨论和示例,请参见第13.20.3节,“MySQL处理GROUP BY”。

 

如何解决这个问题,操作2部

1.首先要从mysql默认模式列表中删除ONLY_FULL_GROUP_BY

2.其次要在配置文件my.cnf中设置默认模式

3.重启mysql

具体操作如下:

1. select @@global.sql_mode 查看模式中是否有only_full_group_by

2. 删除only_full_group_by 

set@@global.sql_mode=
'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,
ERROR_FOR_DIVISION_BY_ZERO,
NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' 

3. 配置my.cnf,增加如下

sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

4. 保存后重启mysql 

systemctl restart mysqld.service

建议去看下mysql5.7后的group by用法

 

对于已经创建项目,并且在云上的数据库资源,持久化配置会成为问题,需要如下操作:

1. 全局配置,对于新建数据库直接生效:

SELECT @@global.sql_mode;

去掉ONLY_FULL_GROUP_BY

SET @@global.sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

2. 对于具体的数据库修改配置

SET sql_mode ='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

 

 

### 问题分析 MySQL版本5.7及之后,默认启用了`sql_mode=only_full_group_by`模式[^2]。该模式要求在`GROUP BY`子句中,所有非聚合字段必须出现在`GROUP BY`列表中,或者这些字段必须是函数依赖的。如果违反这一规则,就会出现类似`Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column`的错误。 以下是解决此问题的详细方法: --- ### 解决方案 #### 方法一:修改SQL查询语句 通过调整SQL查询语句,确保所有非聚合字段都包含在`GROUP BY`子句中。例如: ```sql SELECT column1, column2, column3, COUNT(*) FROM table_name GROUP BY column1, column2, column3; ``` 上述查询语句将`column1`, `column2`, 和`column3`添加到`GROUP BY`子句中,从而满足`ONLY_FULL_GROUP_BY`的要求[^2]。 --- #### 方法二:禁用`ONLY_FULL_GROUP_BY`模式 可以通过修改MySQL的配置文件或临时更改`sql_mode`来禁用`ONLY_FULL_GROUP_BY`模式。 **步骤:** 1. **查找MySQL配置文件** 在Windows系统中,配置文件通常位于`C:/ProgramData/MySQL/MySQL Server x.x/my.ini`[^3];在Linux系统中,配置文件可能位于`/etc/mysql/my.cnf`或`/etc/my.cnf`。 2. **编辑配置文件** 打开配置文件,找到`sql_mode`设置行。例如: ```ini sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,... ``` 将`ONLY_FULL_GROUP_BY`从`sql_mode`中移除。修改后的内容如下: ```ini sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,... ``` 3. **重启MySQL服务** 在命令行中执行以下命令以重启MySQL服务(Windows示例): ```bash net stop mysql net start mysql ``` 或者直接重启计算机以确保配置生效。 4. **验证更改** 登录MySQL并运行以下命令,确认`sql_mode`中不再包含`ONLY_FULL_GROUP_BY`: ```sql SELECT @@sql_mode; ``` --- #### 方法三:使用`ANY_VALUE()`函数 MySQL提供了`ANY_VALUE()`函数,用于明确指定某些字段可以忽略`ONLY_FULL_GROUP_BY`的限制。例如: ```sql SELECT column1, ANY_VALUE(column2), COUNT(*) FROM table_name GROUP BY column1; ``` 在此示例中,`column2`被包装在`ANY_VALUE()`函数中,表示即使它不在`GROUP BY`子句中,也可以安全地使用[^2]。 --- ### 注意事项 - 修改数据库配置文件会影响整个数据库实例的行为,需谨慎操作。 - 如果选择禁用`ONLY_FULL_GROUP_BY`模式,可能会导致查询结果不一致,特别是在数据存在多值的情况下[^3]。 - 推荐优先考虑修改SQL查询语句以符合标准,而不是禁用严格模式。 --- ### 示例代码 以下是一个完整的示例,展示如何解决`Expression #2`错误: ```sql -- 原始查询(报错) SELECT category, product_name, price, COUNT(*) FROM products GROUP BY category; -- 修改后的查询(方法一:添加所有非聚合字段到GROUP BYSELECT category, product_name, price, COUNT(*) FROM products GROUP BY category, product_name, price; -- 修改后的查询(方法三:使用ANY_VALUE()函数) SELECT category, ANY_VALUE(product_name), ANY_VALUE(price), COUNT(*) FROM products GROUP BY category; ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值