报错内容如下:
1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'fbjs.mscc.ContactTime' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by, Time: 0.000000s
1055 - Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'fbjs.mscc.ContactTime' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by, Time: 0.000000s
前情提示:
测试数据库mysql5.6(centOS6.8)、mysql8.0(Mac)
5.6可以执行,8.0报错
测试SQL大致语句:
SELECT msc.CustomerID,msc.CustomerName,mscc.ContactTime FROM membership_customer msc LEFT JOIN membership_customercontact mscc ON (msc.CustomerID = mscc.CustomerID AND mscc.`Status` = 1 ) WHERE msc.`Status` !=4 AND (msc.FollowUpStatus = 2 OR msc.FollowUpStatus = 3 OR msc.`Status` = 6) GROUP BY msc.CustomerID ORDER BY mscc.ContactTime DESC
SELECT msc.CustomerID,msc.CustomerName,msc.AddTime AS CreateTime,msc.EmployeeID,he.EmployeeName,mscc.ContactTime FROM membership_customer msc LEFT JOIN membership_customercontact mscc ON (msc.CustomerID = mscc.CustomerID AND mscc.`Status` = 1 ) LEFT JOIN human_employee he ON he.EmployeeID = msc.EmployeeID WHERE msc.`Status` !=4 AND (msc.FollowUpStatus = 2 OR msc.FollowUpStatus = 3 OR msc.`Status` = 6) AND msc.EmployeeID = '1' GROUP BY msc.CustomerID ORDER BY mscc.ContactTime DESC
在mysql5.7以上的版本中,对于 group by 的这种聚合操作,如果在select 中的列,没有在group by 中出现,那么这个SQL是不合法的,因为列不在group by的从句中,所以对于设置了这个mode的数据库,在使用group by 的时候,就要用MAX(),SUM(),ANT_VALUE()的这种聚合函数,才能完成GROUP BY 的聚合操作 参考文档:
https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html#sql-mode-setting
ONLY_FULL_GROUP_BY的设定,将不允许查询字段包括非聚集列
查询mysql服务器版本:以下命令在终端或者navicat中输入执行均可。 select @@version
#查看sql_mode的语法
SELECT @@GLOBAL.sql_mode;
SELECT @@SESSION.sql_mode; 显示结果:
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
5.6.22-enterprise-commercial-advanced企业版sql_mode默认:
STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
方法一:
查询mysql 1055错误码发现问题为在mysql的配置中如果设置了sql_mode包含ONLY_FULL_GROUP_BY值得话,在进行查询时必须要将select的字段都包含在group by 中。 即 select a,b from xxx group by a,b 否则就会报错
方法二:
#修改sql_mode的语法
通过修改配置文件my.cnf来解决这个问题的。 1. 关闭正在运行的mysql 2. 修改/etc/my.cnf,将sql_mode=中的only_full_group_by给删掉 3. 重启mysql,再执行出错的sql发现能成功执行了
如果没有my.cnf文件,解决方式查看(有模板)https://blog.csdn.net/qq_31708763/article/details/104357798
默认优先选取/etc/my.cnf这个是启动脚本里轮询的第一个位置。
推荐使用更改my.cnf方法更改sql_mode,以防止后续重启mysql服务或者服务器配置失效。另外提一句,8.0版本目前测试是在my.cnf中配置忽略大小写无用,除非在数据库初始化时候指定,估计是高版本更新都是这样。
sql_mode常用值:
ONLY_FULL_GROUP_BY: 对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP
BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中
NO_AUTO_VALUE_ON_ZERO: 该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户
希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。
STRICT_TRANS_TABLES: 在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
NO_ZERO_IN_DATE: 在严格模式下,不允许日期和月份为零
NO_ZERO_DATE: 设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。
ERROR_FOR_DIVISION_BY_ZERO: 在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如
果未给出该模式,那么数据被零除时MySQL返回NULL
NO_AUTO_CREATE_USER: 禁止GRANT创建密码为空的用户
NO_ENGINE_SUBSTITUTION:
如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常
PIPES_AS_CONCAT:
将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似
ANSI_QUOTES: 启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符
方法三:修改global sql_mode:
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
修改之后,重新新建查询,测试结果OK,如下图:
因为方法3太方便了,也无须管配置文件,只需在命令行或者客户端软件执行SQL语句就行,接下来测试重启mysql服务此法是否依旧有效。(此处直接重启了电脑)
sudo /usr/local/mysql/support-files/mysql.server start
sudo /usr/local/mysql/support-files/mysql.server stop
sudo /usr/local/mysql/support-files/mysql.server restart
重启后测试无效。恢复原来的了。
最后,推荐使用方法二,更改配置文件,Mac下注意目录权限问题,如果需要也可以在系统偏好设置里指定配置文件位置,如下图所示: