今天在部署一趟测试环境的服务,各种配置文件都配好了,启动服务后台报错,解决后记录一下,小伙伴们也可以看看!
### Cause: java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'storage.storage_category.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'storage.storage_category.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by] <----
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'storage.storage_category.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
### The error may exist in URL [jar:file:/home/storage/storage_starter-1.0-SNAPSHOT.jar!/BOOT-INF/classes!/mapper/StorageCategoryMapper.xml]
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select id, first_category, code, second_category, creator, updator, create_time, update_time, is_deleted from storage.storage_category WHERE first_category = ? and is_deleted = 0 group by second_category order by id
在网上也查了一些信息:
这个错误信息是由MySQL数据库返回的,它指出SQL查询中违反了ONLY_FULL_GROUP_BY
SQL模式的要求。当MySQL启用了ONLY_FULL_GROUP_BY
模式时,任何SELECT列表、HAVING条件或ORDER BY列表中的非聚合列都必须出现在GROUP BY子句中。如果它们不在GROUP BY子句中,且不是通过聚合函数(如SUM(), COUNT(), MAX(), MIN(), AVG()等)处理的,就会抛出这个错误。
错误信息中提到的storage.storage_category.id
这一列没有被包含在GROUP BY子句中,同时也没有被聚合函数处理,因此违反了ONLY_FULL_GROUP_BY
规则。
要解决这个问题,可以采取以下几种方法之一:
1. 修改SQL查询:确保SELECT列表中的所有非聚合列都包含在GROUP BY子句中。例如,如果你的查询类似于这样:
SELECT storage_category.id, COUNT(*)
FROM your_table
GROUP BY some_other_column;
需要将storage_category.id
也加入到GROUP BY子句中:
SELECT storage_category.id, COUNT(*)
FROM your_table
GROUP BY storage_category.id, some_other_column;
2. 关闭ONLY_FULL_GROUP_BY模式:如果你确定你的查询逻辑是正确的,并且不需要完全符合ONLY_FULL_GROUP_BY
的要求,你可以关闭这个SQL模式。关闭该模式的方法是在MySQL配置文件中设置或者在运行时执行以下SQL命令:
SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
或者针对当前会话:
SET SESSION sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
3.使用聚合函数:如果storage.storage_category.id
列不需要单独列出每个唯一的值,而是可以通过聚合函数来汇总,比如取最小值或最大值,你可以修改查询来使用这些聚合函数。
SELECT MIN(storage_category.id) AS min_id, COUNT(*)
FROM your_table
GROUP BY some_other_column;
我在线上环境正常部署一切正常,所以我采用了第二种方式 关闭ONLY_FULL_GROUP_BY模式。
下面看看如何关闭ONLY_FULL_GROUP_BY模式?
- 找到MySQL的配置文件。在Linux系统中,配置文件通常位于
/etc/mysql/my.cnf
或/etc/my.cnf
。如果是其他操作系统,如Windows,配置文件的位置可能会有所不同。- 使用文本编辑器打开配置文件。
- 在配置文件中找到
[mysqld]
部分。- 在
[mysqld]
部分下添加或修改以下行,将sql_mode
的值设置为不包含ONLY_FULL_GROUP_BY
的模式。例如,可以设置为空字符串(禁用所有SQL模式)或指定其他你需要的SQL模式,但确保不包括ONLY_FULL_GROUP_BY
。
[mysqld]
sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
请注意,配置文件中可能已经存在其他的sql_mode
值,你需要将ONLY_FULL_GROUP_BY
选项从其中移除,而不是简单地添加一个新的sql_mode
行。
- 保存并关闭配置文件。
- 重启MySQL服务,使配置文件生效。在Linux系统中,可以使用以下命令重启MySQL服务:
sudo systemctl restart mysql
请注意,关闭ONLY_FULL_GROUP_BY模式可能会导致一些查询结果不准确,因为在没有该模式的情况下,MySQL允许非聚合列出现在SELECT列表或HAVING条件中,即使它们没有包含在GROUP BY子句中。因此,在关闭该模式之前,请确保你了解可能的影响,并仔细考虑是否真的需要关闭它。如果只是为了临时解决某个查询问题,你也可以考虑使用SET命令在运行时临时禁用ONLY_FULL_GROUP_BY选项,而不是修改配置文件。