禁用ONLY_FULL_GROUP_BY模式

这是由于MySQL启用了ONLY_FULL_GROUP_BY模式导致的。以下是禁用该模式的三种方法,结合你的需求选择最合适的方案:

一、临时禁用(重启后失效)

1. 当前会话禁用

直接在SQL客户端执行以下命令,仅对当前数据库连接有效:

SET SESSION sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
2. 全局禁用

修改全局设置,对所有新连接生效(但重启MySQL服务后失效):

SET GLOBAL sql_mode = (SELECT REPLACE(@@GLOBAL.sql_mode, 'ONLY_FULL_GROUP_BY', ''));

二、永久禁用(需修改配置文件)

步骤
  1. 找到MySQL配置文件

    • Windowsmy.ini(通常位于MySQL安装目录或C:\ProgramData\MySQL\MySQL Server 8.0)。
    • Linux/etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf
  2. 修改配置: 在 [mysqld] 部分添加或修改 sql_mode,移除 ONLY_FULL_GROUP_BY。 示例配置:

    [mysqld] sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION

  3. 重启MySQL服务

    • Windows:通过服务管理器重启MySQL服务。
    • Linux:执行 sudo systemctl restart mysql
  4. 验证

    SELECT @@GLOBAL.sql_mode;

    确认输出中不再包含 ONLY_FULL_GROUP_BY

三、查询优化(推荐)

如果不想修改数据库配置,可以通过以下方式调整SQL语句,使其符合ONLY_FULL_GROUP_BY规则:

1. 确保所有非聚合列在GROUP BY

修改你的SQL,将SELECT列表中的非聚合列(如network_type)添加到GROUP BY子句:

GROUP BY t.id, cdn.cdn_device_network.network_type

2. 使用聚合函数包裹非聚合列

对不需要分组的列使用ANY_VALUE()函数:

SELECT ANY_VALUE(network_type) AS network_type, ... FROM ... GROUP BY t.id

四、注意事项

  1. 数据一致性风险:禁用ONLY_FULL_GROUP_BY可能导致查询结果不确定,建议生产环境谨慎操作。
  2. 配置文件优先级:确保修改的配置文件是MySQL实际加载的(可能存在多个配置文件,优先级以最后加载的为准) 。
     
  3. MySQL版本差异:MySQL 8.0默认启用此模式,需通过配置文件永久修改 。

总结

  • 快速修复:临时禁用(方法一)适合紧急调试。
  • 长期方案:修改配置文件(方法二)确保重启后生效。
  • 最佳实践:优化SQL查询(方法三),避免依赖数据库模式

你可能感兴趣的:(Java,MySQL)