在捣鼓 MySQL左联多个表做分组查询数据重复问题解决 时,遇到了报错:

1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.base.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by, Time: 0.001000s

百度翻译:

1055 - SELECT 列表的表达式 #1 不在 GROUP BY 子句中,并且包含非聚合列 “test.base.id”,该列在功能上不依赖于 GROUP BY 子句的列;这与 sql_mode=only_full_group_by 不兼容,时间:0.001000s

这里提取到一个关键词 ONLY_FULL_GROUP_BY SQL 模式。网上转了一圈,大概的情况就是,MySQL 5.7 开始默认开启 ONLY_FULL_GROUP_BY 模式,查询时会做这样的检查:select 后面查询的字段有没有出现在 group by 中。也提供了几种解决方法:

  • 修改 sql 使其遵守 only_full_group_by 规则
  • 关闭 only_full_group_by 规则
  • 将 MySql 的版本降到 5.7 以下

mysql -V 查到本地 docker 安装的 MySQL 服务器版本为 5.7.36show variables like '%sql_mode%'; 查到 sql_mode 的值里也确实有 ONLY_FULL_GROUP_BY

首先降低 MySQL 版本不推荐,其次也不推荐关闭 only_full_group_by 规则,这是没有办法解决的时候的办法。

参考教程里有提到两种修改 sql 使其遵守或者规避规则的方法:

  • 在 group by 后面追加上 select 的列
  • 使用子查询或先分组再联查的方式规避规则

本来已经准备按照这两种方式改了,突然发现,我的情况不太一样。我的是主表关联字段不是主键,但起到主键的作用,并且还创建了 unique 的索引。将 GROUP BY 的对象改为主键,然后不报错了。

SELECT `base`.*,
SUM(user_operation2.num) AS operation2_num, 
SUM(user_operation2.money) AS operation2_money
FROM base
LEFT JOIN user_operation2 ON user_operation2.user_id = base.user_id
GROUP BY base.user_id
LIMIT 0 ,10

之后测试发现,将主表关联字段设置为非 null 之后,报错也消失了。

参考教程:
真正有效解决 ONLY_FULL_GROUP_BY 的问题
MySql 报错 only_full_group_by 的解决办法