美文网首页
记一个 MySQL 版本导致的问题

记一个 MySQL 版本导致的问题

作者: 程序员小西 | 来源:发表于2022-03-18 14:26 被阅读0次

    问题

    线上遇到MYSQL GROUP By 查询出现 only_full_group_by 的问题,错误提示是:

    MySQLdb._exceptions.OperationalError: (1055, "Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'train.course_study.company_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by")

    查官方文档,原来是MySQL5.7以上版本一个属性配置变更导致的问题,而我们系统刚好最近升级到8.0。

    为什么会出现这种情况呢?我测试环境跑的好好的

    原因

    我们知道Group By 是用来将字段值相同记录做聚查询的语句,例如将用户表按性别分组, 统计男女各有多少人可以用group by查询

    select gender, count(id)fromstudent_user

    但是,如果select 查询字段中有非聚合字段,同时该字段没有出现在where条件或group by 语句中, 例如:

    SELECTgender,COUNT(id), emailFROMstudent_userGROUPBYgender

    上面这条语句把email也可以查出来,在MySQL5.6以下版本不会报错,不过 email 字段你查出来也没有任何意义,也不知道email对应的是哪条记录。

    从MySQL5.7开始,系统默认不支持这种查询,这种行为是通过一个sql_mode 设置成ONLY_FULL_GROUP_BY的配置来控制的。

    通过命令可以查到MySQL5.7版本显示:

    SELECT @@GLOBAL.sql_mode;

    sql_mode中有 ONLY_FULL_GROUP_BY 意味着 select 中的字段要么出现在group by 里面,要么是使用了聚合函数的字段。否则就会报开头那种错误。

    回过来看我们实际业务场景中的一个问题

    select user_id, company_id, sum(learn_time) from student_user group by user_id

    student_user表记录了每个学员多条学习记录,上面这条语句用来统计每个人的总学习时长,user_id 与 company id 是多对一的关系, 就是说一个 user_id 只可能在一个company下面,执行这条语句是希望统计每个user学习时长,顺便把他所在的company_id也找出来。但我并没有把company_id 放在 group by 语句后面。

    这时候我们测试环境没问题,数据与预期符合一直。数据库版本是mysql5.6。到了正式环境mysql5.7就无法执行。因为 company_id 出现在查询字段中,但没有出现在where语句或者是 group by 语句中。

    解决办法

    第一种方式:在 group by 后面加上要查询的非聚合字段, 比如我这里加上 company_id,相当于通过 user_id+comapny_id 来分组,因为user_id和company_id 是多对一关系,所以 分组查询的时候两者返回的结果是一样的。

    select user_id, company_id, sum(learn_time) from student_user group by user_id, company_id

    第二种方式:使用 any_value 函数, 在非聚合字段上使用函数

    select user_id, any_value(company_id), sum(learn_time) from student_user group by user_id

    第三种方式:将sql_mode配置中的ONLY_FULL_GROUP_BY去掉, 重启MySQL服务,当然不建议去掉这个配置。这样可以保证你写的SQL更严谨

    后记

    测试环境与生产环境保持绝对一致的环境,包括服务器和数据库以及依赖的第三方库,提前发现问题。

    相关文章

      网友评论

          本文标题:记一个 MySQL 版本导致的问题

          本文链接:https://www.haomeiwen.com/subject/smwidrtx.html