错误:myql5.7不兼容group by

当遇到MySQL5.7中由于`ONLY_FULL_GROUP_BY`模式导致的错误时,可以采取三种策略:一是修改MySQL配置文件,移除`ONLY_FULL_GROUP_BY`限制;二是升级数据库至8.0版本;三是调整SQL查询语句,例如使用`ANY_VALUE`函数。这些方法可以帮助你避免不兼容问题并优化查询效率。

报错:Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘database_tl.emp.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去掉。
方法二:将数据库升级为8.0
方法三:修改使用到group by的sql语句
比如 SELECT id,code,name FROM a GROUP BY code;
改为 SELECT any_value(id),any_value(name),code FROM a GROUP BY code;

<think>我们讨论的是MySQL 8.0如何兼容MySQL 5.7GROUP BY行为。 在MySQL 5.7中,默认的SQL模式包括ONLY_FULL_GROUP_BY,但实际在5.7之前,这个模式默认是不启用的,因此允许一些非标准化的GROUP BY使用。 而在MySQL 8.0中,ONLY_FULL_GROUP_BY模式默认是启用的,这会导致在5.7中可以运行的一些GROUP BY查询在8.0中报错。 问题:如何让MySQL 8.0兼容5.7GROUP BY行为(即禁用ONLY_FULL_GROUP_BY)? 解决方案: 1. 临时修改:在当前会话中修改SQL模式,移除ONLY_FULL_GROUP_BY。 2. 永久修改:修改MySQL配置文件,调整sql_mode参数,移除ONLY_FULL_GROUP_BY。 具体步骤: 方法1:临时修改(仅对当前会话有效) 在连接到数据库后,执行以下SQL语句: ```sql SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '')); ``` 方法2:永久修改(需要修改配置文件并重启MySQL服务) 步骤: 1. 找到MySQL的配置文件my.cnf(Linux)或my.ini(Windows)。 2. 在[mysqld]部分添加或修改sql_mode,移除ONLY_FULL_GROUP_BY。 例如,如果当前的sql_mode是: sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 修改为: sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION 3. 保存并重启MySQL服务。 注意:移除ONLY_FULL_GROUP_BY可能会引发数据不一致的问题,因为MySQL允许在GROUP BY子句中不列出所有非聚合列,这时它会任意返回这些列中的值。在标准SQL中这是不允许的。因此,建议在应用程序中尽量使用符合标准的GROUP BY写法。 示例代码(临时修改): 假设我们有一个查询在5.7中可以运行,但在8.0中因为ONLY_FULL_GROUP_BY而报错,我们可以这样在当前会话中修改: ```sql -- 查看当前的sql_mode SELECT @@sql_mode; -- 移除ONLY_FULL_GROUP_BY SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', '')); -- 然后执行原来的GROUP BY查询 -- 例如: SELECT department, employee_name, salary FROM employees GROUP BY department; ``` 注意:上面的查询在ONLY_FULL_GROUP_BY禁用的情况下可以运行,但employee_name和salary的值可能是任意值(取决于MySQL的实现,通常是组内的第一行)。在标准SQL中,应该使用聚合函数(如MAX, MIN, AVG等)来处理非GROUP BY列。 解释: 在MySQL 8.0中,默认的sql_mode包含ONLY_FULL_GROUP_BY,这要求SELECT列表中的非聚合列必须出现在GROUP BY子句中,或者被聚合函数包裹。为了兼容5.7的行为(即不启用ONLY_FULL_GROUP_BY),我们可以移除这个模式。 但是,请注意,在MySQL 5.7中,默认的sql_mode实际上是包括ONLY_FULL_GROUP_BY的(从5.7.5开始)。所以,如果你的5.7环境没有启用,那是因为有人修改了配置。因此,更准确地说,我们是要让MySQL 8.0的行为与某个特定配置的5.7一致(即没有启用ONLY_FULL_GROUP_BY5.7)。 相关问题: 1. 如何查看当前MySQL的sql_mode? 2. 除了移除ONLY_FULL_GROUP_BY,还有哪些方法可以修复因为ONLY_FULL_GROUP_BY导致的错误? 3. 在启用ONLY_FULL_GROUP_BY的情况下,如何正确编写GROUP BY查询? 4. MySQL 8.05.7在默认配置上还有哪些主要区别?</think>### MySQL 8.0 兼容 5.7GROUP BY 行为解决方案 在 MySQL 5.7 中,默认配置允许非标准化的 `GROUP BY` 查询(即 SELECT 列表包含非聚合列且未在 GROUP BY 子句中列出)。而 MySQL 8.0 默认启用了 `ONLY_FULL_GROUP_BY` 模式,会拒绝此类查询。以下是兼容解决方案: #### 方法 1:修改 SQL 模式(推荐) ```sql -- 查看当前 SQL 模式 SELECT @@sql_mode; -- 移除 ONLY_FULL_GROUP_BY(临时生效) SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'; -- 永久生效(需修改配置文件) -- 在 my.cnf 或 my.ini 的 [mysqld] 部分添加: [mysqld] sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION" ``` #### 方法 2:使用 ANY_VALUE() 函数(标准做法) ```sql SELECT department_id, ANY_VALUE(department_name) AS dept_name, -- 明确标记非聚合列 AVG(salary) AS avg_salary FROM employees GROUP BY department_id; ``` #### 方法 3:完整列出所有非聚合列 ```sql SELECT department_id, department_name, -- 必须包含在 GROUP BY 中 AVG(salary) AS avg_salary FROM employees GROUP BY department_id, department_name; -- 列出所有非聚合列 ``` #### 方法 4:启用 5.7 兼容模式(不推荐) ```sql SET GLOBAL sql_mode = sys.list_drop(@@sql_mode, 'ONLY_FULL_GROUP_BY'); ``` ### 关键差异说明 | **特性** | **MySQL 5.7** | **MySQL 8.0** | |------------------|--------------------------------|--------------------------------| | 默认 SQL 模式 | 未启用 ONLY_FULL_GROUP_BY | 启用 ONLY_FULL_GROUP_BY | | 非标准 GROUP BY | 允许(返回任意值) | 报错 (1055) | | 数据一致性 | 可能不一致 | 强制一致 | ### 建议方案 1. **生产环境**:使用方法 2(`ANY_VALUE()`),既保持标准兼容性又明确开发意图 2. **迁移过渡期**:临时使用方法 1 修改 SQL 模式 3. **长期方案**:重构查询遵循 SQL 标准(GROUP BY 包含所有非聚合列) > ⚠️ 警告:完全禁用 `ONLY_FULL_GROUP_BY` 可能导致数据不一致(MySQL 可能随机返回组内值)
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

静安书以沫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值