插件窝 干货文章 MySQL 分组查询中 GROUP BY 要求:何时需要禁用 ONLY_FULL_GROUP_BY 模式?

MySQL 分组查询中 GROUP BY 要求:何时需要禁用 ONLY_FULL_GROUP_BY 模式?

GROUP 查询 禁用 MySQL 659    来源:    2025-03-31

MySQL 中禁用 ONLY_FULL_GROUP_BY 模式的情况分析

ONLY_FULL_GROUP_BY 模式简介

ONLY_FULL_GROUP_BY 是 MySQL 5.7 及更高版本中默认启用的 SQL 模式之一,它对 GROUP BY 查询施加了更严格的语义检查。在此模式下: - SELECT 列表中的非聚合列必须出现在 GROUP BY 子句中 - HAVING 条件只能引用 GROUP BY 中的列或聚合函数

需要禁用 ONLY_FULL_GROUP_BY 的典型场景

  1. 遗留系统兼容性

    • 从旧版本 MySQL 升级后,原有查询可能不符合新标准
    • 需要暂时禁用以保持系统运行,同时逐步修正查询
  2. 特定查询需求

    • 需要从分组结果中选择非分组列(MySQL 会从每组中随机选择一个值)
    • 例如:SELECT user_id, username FROM users GROUP BY user_id(username 不在 GROUP BY 中)
  3. 简化复杂查询

    • 某些复杂分析查询在严格模式下难以编写
    • 需要禁用以获得更灵活的查询能力

禁用方法

临时禁用(当前会话)

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

永久禁用

修改 MySQL 配置文件(my.cnf 或 my.ini):

[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

然后重启 MySQL 服务。

最佳实践建议

  1. 优先修正查询:尽可能修改查询使其符合 ONLY_FULL_GROUP_BY 标准
  2. 使用 ANY_VALUE() 函数:MySQL 5.7+ 提供了 ANY_VALUE() 函数明确表示接受任意值 sql SELECT user_id, ANY_VALUE(username) FROM users GROUP BY user_id
  3. 考虑使用窗口函数:对于复杂分析,MySQL 8.0+ 的窗口函数可能是更好的选择

禁用 ONLY_FULL_GROUP_BY 应视为临时解决方案,长期来看修正查询是更可靠的做法。