问题描述:同一段使用了group by来进行分组的SQL,在本地的MySQL执行是没问题的,但放到docker上安装的MySQL(版本是5.7)去执行就有问题,如下图:
问题出现的原因:默认情况下,MySQL5.7镜像中的sql_mode含有only_full_group_by,如果MySQL启用了only_full_group_by SQL模式的话,MySQL将拒绝选择列表,即不能使用group by
查看SQL模式可用下面这条SQL:
select @@global.sql_mode
本地MySQL与docker上安装的MySQL的SQL模式的对比:
解决方案:修改MySQL的配置文件设置SQL模式(即将SQL模式默认有的only_full_group_by给去掉),在配置文件的[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
注意:网上有方法说是直接在连接工具里执行以下SQL进行设置
set @@global.sql_mode
=’STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION’;
这种方法亲测无效且容器一重启就又会恢复为默认的SQL模式;网上还有方法说是进入容器,然后修改/etc/mysql/mysql.conf.d/mysqld.cnf文件进行配置,这种方法亲测需要先给容器安装vim命令,否则无法修改,因为容器里是没有vim命令的;综上,我的做法是先将已有的MySQL容器删除(删除前注意将数据备份),然后重新启动容器并指定数据目录和配置文件,指定数据目录的目的是将容器内部的数据目录映射到宿主机,这样即使容器被删除了那数据依然还在宿主机,指定配置文件的目是将宿主机上的配置文件映射覆盖到容器内部,这样如果要修改容器的配置文件的话,就直接修改宿主机上的
步骤:
- 列出正在运行的容器
docker ps
- 将MySQL容器停掉(注意停之前先将数据备份)
docker stop bd041f156ec9
- 将MySQL容器删除
docker rm bd041f156ec9
- 重新启动MySQL容器,指定数据目录跟配置文件
docker run -d -p 3308:3306 -v /etc/my.cnf:/etc/mysql/mysql.conf.d/mysqld.cnf -v /mySoft/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root --name mysql5.7 mysql:5.7
#-v是将宿主机上的文件/文件夹与容器内部的文件/文件夹进行映射
#这里是将宿主机上/etc目录下的my.cnf文件与容器内部/etc/mysql/mysql.conf.d目录下的mysqld.cnf文件进行映射,即容器内部使用的配置文件就是宿主机上的/etc/my.cnf文件
#同时还将宿主机上的/mySoft/mysql/data文件夹与容器内部的/var/lib/mysql文件夹进行映射,即容器内部的数据会保存到宿主机上的/mySoft/mysql/data目录去
操作截图如下:
- 用连接工具测试启动的MySQL能否连接上
- 修改宿主机上的配置文件加上SQL模式的相关配置
vim /etc/my.cnf
操作截图如下:
然后问题就解决了: