• 设为首页
  • 收藏本站
  • 积分充值
  • VIP赞助
  • 手机版
  • 微博
  • 微信
    微信公众号 添加方式:
    1:搜索微信号(888888
    2:扫描左侧二维码
  • 快捷导航
    福建二哥 门户 查看主题

    MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错问题及解决方案

    发布者: 雪落无声 | 发布时间: 2025-6-14 14:26| 查看数: 54| 评论数: 0|帖子模式

    MySQL分组的时候遇到ONLY_FULL_GROUP_BY报错问题


    一、ONLY_FULL_GROUP_BY 错误的根本原因

    MySQL 5.7 及以上版本默认启用了
    1. sql_mode=only_full_group_by
    复制代码
    严格模式。
    该模式强制要求:

    • SELECT 中的非聚合字段必须出现在
      1. GROUP BY
      复制代码
      子句中;
    • 所有非聚合字段需通过聚合函数(如
      1. MAX
      复制代码
      1. MIN
      复制代码
      1. SUM
      复制代码
      )处理,或显式声明分组依据。
    触发场景示例
    1. SELECT name, age, SUM(sales) FROM orders GROUP BY name;  
    复制代码
    1. age
    复制代码
    未出现在
    1. GROUP BY
    复制代码
    中且未使用聚合函数,MySQL 无法确定如何为同一
    1. name
    复制代码
    的不同
    1. age
    复制代码
    值返回结果,导致报错。

    二、解决方案


    1. 调整 SQL 语句

    方案一:添加缺失的字段到 GROUP BY
    将所有 SELECT 中的非聚合字段加入分组条件:
    1. SELECT name, age, SUM(sales) FROM orders GROUP BY name, age;  
    复制代码
    适用场景:需精确按多字段分组,但可能导致分组维度增加,影响性能。
    方案二:使用聚合函数包裹非分组字段
    通过
    1. MAX()
    复制代码
    1. MIN()
    复制代码
    1. ANY_VALUE()
    复制代码
    处理字段:
    1. SELECT name, MAX(age) AS latest_age, SUM(sales) FROM orders GROUP BY name;  
    复制代码
    1. ANY_VALUE(age)
    复制代码
    会从分组中随机选择一个值,适用于无需精确值的场景。
    方案三:使用子查询或临时表
    将复杂逻辑拆分为子查询,分步处理:
    1. WITH grouped_data AS (  
    2.   SELECT name, SUM(sales) AS total_sales  
    3.   FROM orders  
    4.   GROUP BY name  
    5. )  
    6. SELECT g.name, o.age, g.total_sales  
    7. FROM grouped_data g  
    8. JOIN orders o ON g.name = o.name;  
    复制代码
    2. 临时或永久关闭 ONLY_FULL_GROUP_BY

    临时禁用(会话级)
    1. SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE...';  -- 移除 ONLY_FULL_GROUP_BY  
    复制代码
    永久禁用(需修改配置文件):
    1. [mysqld]  
    2. sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE...  -- 去掉 ONLY_FULL_GROUP_BY  
    复制代码
    风险:可能导致查询结果不可预测,仅建议在测试环境使用。

    3. 使用 ANY_VALUE() 函数(推荐)

    从 MySQL 5.7.5 开始,可用
    1. ANY_VALUE()
    复制代码
    显式抑制错误:
    1. SELECT name, ANY_VALUE(age), SUM(sales) FROM orders GROUP BY name;  
    复制代码
    此函数会从分组中返回任意一个值,适用于无需精确值的业务场景。

    三、规避问题的建议

    遵循严格模式

    • 启用
      1. ONLY_FULL_GROUP_BY
      复制代码
      可提升数据准确性,避免不可预测的查询结果。
    • 强制要求开发人员按规范编写 SQL,确保所有非聚合字段明确处理。
    优化查询设计

    • 避免在
      1. SELECT
      复制代码
      中引入不必要的字段,减少歧义。
    • 优先使用聚合函数或子查询处理复杂逻辑。
    索引优化

      1. GROUP BY
      复制代码
      涉及的字段和关联条件添加索引,提升性能。
    代码审查与测试

    • 在代码审查中检查
      1. GROUP BY
      复制代码
      语句的规范性。
    • 在测试环境启用严格模式,提前暴露问题。

    总结

    根本矛盾
    1. ONLY_FULL_GROUP_BY
    复制代码
    模式通过严格性保障数据一致性,但需要开发者遵循 SQL 标准。
    最佳实践

    • 优先通过调整 SQL 语句(如聚合函数、子查询)解决问题;
    • 仅在必要时临时禁用严格模式,生产环境慎用;
    • 利用
      1. ANY_VALUE()
      复制代码
      作为灵活性补充,但需评估业务场景的准确性需求。
    通过上述方法,可在兼容性、性能和数据准确性之间取得平衡。
    以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    来源:https://www.jb51.net/database/339859h2d.htm
    免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

    最新评论

    QQ Archiver 手机版 小黑屋 福建二哥 ( 闽ICP备2022004717号|闽公网安备35052402000345号 )

    Powered by Discuz! X3.5 © 2001-2023

    快速回复 返回顶部 返回列表