一、环境

MySQL版本:MySQL5.7.22表结构:CREATE TABLE `crm_report_accounting_income` (`id` int(10) NOT NULL AUTO_INCREMENT,`contract_id` int(10) NOT NULL,`contract_no` varchar(50) NOT NULL,`date` int(8) NOT NULL,`city_id` int(11) NOT NULL DEFAULT '0' COMMENT '城市id',`city_name` varchar(50) DEFAULT NULL,`adviser_id` int(10) NOT NULL,`adviser_name` varchar(50) DEFAULT NULL,`accounting` decimal(15,2) NOT NULL COMMENT 'xx',`receivable` decimal(15,2) NOT NULL DEFAULT '0.00' COMMENT '当xx',`contract_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '1:xx合同;2:xx合同;3:xx合同',PRIMARY KEY (`id`),KEY `contract_id` (`contract_id`),KEY `date` (`date`),KEY `city_id` (`city_id`)
) ENGINE=InnoDB AUTO_INCREMENT=734525 DEFAULT CHARSET=utf8

二、业务问题


*  基本信息,由于合同号太多,所以这边就以一个有重复数据的合同id为例dba:aif_db> select contract_id,contract_no,receivable,date from crm_report_accounting_income_2015_online where contract_id = 27310;
+-------------+----------------------------+------------+----------+
| contract_id | contract_no                | receivable | date     |
+-------------+----------------------------+------------+----------+
|       27310 | A00-SHEN-05-2018-06-004613 |    2941.18 | 20180628 |
|       27310 | A00-SHEN-05-2018-06-004613 |    5882.36 | 20180629 |
|       27310 | A00-SHEN-05-2018-06-004613 |    8823.54 | 20180630 |
|       27310 | A00-SHEN-05-2018-06-004613 |   11764.72 | 20180701 |
|       27310 | A00-SHEN-05-2018-06-004613 |   14705.90 | 20180702 |
|       27310 | A00-SHEN-05-2018-06-004613 |   17647.08 | 20180703 |
|       27310 | A00-SHEN-05-2018-06-004613 |   20588.26 | 20180704 |
|       27310 | A00-SHEN-05-2018-06-004613 |   23529.44 | 20180705 |
|       27310 | A00-SHEN-05-2018-06-004613 |   26470.62 | 20180706 |
|       27310 | A00-SHEN-05-2018-06-004613 |   29411.80 | 20180707 |
|       27310 | A00-SHEN-05-2018-06-004613 |   32352.98 | 20180708 |
|       27310 | A00-SHEN-05-2018-06-004613 |   35294.16 | 20180709 |
+-------------+----------------------------+------------+----------+
12 rows in set (0.00 sec)* 查询每个最新合同的信息,由于合同号太多,所以这边就以一个有重复数据的合同id为例select contract_no, contract_id, city_name, receivable,date from
(select * from crm_report_accounting_income_2015_online  where contract_id = 27310 ORDER BY `date` desc) p GROUP BY contract_id+----------------------------+-------------+-----------+------------+----------+
| contract_no                | contract_id | city_name | receivable | date     |
+----------------------------+-------------+-----------+------------+----------+
| A00-xxxx-05-2018-06-xxxxxx |       xxxxx | 沈阳      |    2941.18 | 20180628 |
+----------------------------+-------------+-----------+------------+----------+
1 row in set (0.00 sec)

以上看到的写法,是通过子查询写的,5.6查询没问题,5.7就变成了以上的结果,很明显得到的答案不是业务想要的

究其原因还是因为,MySQL5.7 sql mode更加严格了,如果设置sql_mode = ONLY_FULL_GROUP_BY, 那么以上SQL就会报错

因为sql_mode = ONLY_FULL_GROUP_BY 要求符合SQL 92标准,即:select列表里只能出现分组列(即group by后面的列)和聚合函数(max,min等等)

然而为了兼容5.6,我们设置sql_mode='', 所以我们的Group by 在子查询中就跟5.6就不一致了

当然,我们应该避免不标准的SQL写法,这样的问题,我们的解法就是调整业务的SQL语句,改写成SQL 92标准的语法

那么以上SQL语句应该调整为:

selectcontract_no,e.contract_id,city_name,receivable,date
fromcrm_report_accounting_income_2015_online e,( select contract_id , max(date) max_date from  crm_report_accounting_income_2015_online where contract_id = 27310 group by contract_id  ) t
wheree.contract_id = t.contract_idand e.date = t.max_date+----------------------------+-------------+-----------+------------+----------+
| contract_no                | contract_id | city_name | receivable | date     |
+----------------------------+-------------+-----------+------------+----------+
| A00-xxxx-05-2018-06-004613 |       27310 | xxxx      |   35294.16 | 20180709 |
+----------------------------+-------------+-----------+------------+----------+
1 row in set (0.00 sec)

以上都还是需要业务代码修改,这样如果没有提前发现问题,岂不是会导致业务出错了?有没有更好的办法?

MySQL方面其实还是可以配置相关的参数的:

dba:aif_db> set optimizer_switch='derived_merge=off';
Query OK, 0 rows affected (0.00 sec)dbadmin:aifangcrm_db> select contract_no, contract_id, city_name, receivable,date from-> (select * from crm_report_accounting_income_2015_online  where contract_id = 27310 ORDER BY `date` desc) p GROUP BY contract_id-> ;
+----------------------------+-------------+-----------+------------+----------+
| contract_no                | contract_id | city_name | receivable | date     |
+----------------------------+-------------+-----------+------------+----------+
| A00-xxxx-05-2018-06-004613 |       27310 | xxxx      |   35294.16 | 20180709 |
+----------------------------+-------------+-----------+------------+----------+
1 row in set (0.00 sec)

三、总结

  • SQL语法应该要按照标准的SQL92来写
  • 数据库升级到5.7之后,应该提前监控处group by + 子查询的情况,提前告知业务修改业务代码
  • 设置参数也能解决问题,但是这个参数毕竟是5.7新增的,如果关闭后,以后会不会导致其他的bug就不知晓了

最后,还是希望能够修改query 语句到标准语法,如果出现业务问题,可以让业务修改参数快速解决问题,然后再修改语句比较与时俱进

MySQL运维实战系列:MySQL5.7 Group By 问题相关推荐

  1. openstack运维实战系列(十)之nova指定compute节点和IP地址

    1. 背景需求 在openstack中,nova负责openstack虚拟机的生命周期的管理,neutron则负责虚拟机的网络管理工作,默认情况下,创建一台虚拟机,nova会根据nova-schedu ...

  2. openstack运维实战系列(一)之keystone用户建立

    1. 前言 在生产环境中,使用openstack已经有1年多的时间了,苦于一直没有时间,加上工作带来的懒惰,一直迟迟没有对openstack方面的知识做个总结,趁着年底,把过去一年多在生产环境中所遇到 ...

  3. MySQL运维实战 之 PHP访问MySQL你使用对了吗

    大家都知道,slow query系统做的好不好,直接决定了解决slow query的效率问题 一个数据库管理平台,拥有一个好的slow query系统,基本上就拥有了解锁性能问题的钥匙 但是今天主要分 ...

  4. openstack运维实战系列(十七)之glance与ceph结合

    1. 需求说明 glance作为openstack中p_w_picpath服务,支持多种适配器,支持将p_w_picpath存放到本地文件系统,http服务器,ceph分布式文件系统,glusterf ...

  5. 运维人员mysql如何访问_MySQL运维实战 之 PHP访问MySQL你使用对了吗

    原标题:MySQL运维实战 之 PHP访问MySQL你使用对了吗 大家都知道,slow query系统做的好不好,直接决定了解决slow query的效率问题 一个数据库管理平台,拥有一个好的slow ...

  6. MySQL运维(二)MySQL分库分表概念及实战、读取分离详解

    MySQL运维(二)MySQL分库分表详解.读取分离详解 1.MySQL分库分表相关概念 1.1 分库分表概念 1.1.1 分库的原因 分库:就是一个数据库分成多个数据库,部署到不同机器. 如果业务量 ...

  7. 高性能Mysql运维应用实战-高俊峰-专题视频课程

    高性能Mysql运维应用实战-8242人已学习 课程介绍         爱维Linux独家出品,本课程从mysql运维的方方面面进行介绍,主要对mysql版本的选择,mysql平台的部署,优化.调优 ...

  8. mysql系列问答题_(2)MySQL运维基础知识面试问答题

    面试题001:请解释关系型数据库概念及主要特点? 面试题002:请说出关系型数据库的典型产品.特点及应用场景? 面试题003:请解释非关系型数据库概念及主要特点? 面试题004:请说出非关系型数据库的 ...

  9. 运维实战 LNMP框架安装

    运维实战 LNMP框架 架构简介 前期准备 MySQL的安装 MySQL的初始化 PHP的安装 参数的含义 Nginx与PHP的对接 PHPMyAdmin的安装与配置 Memcache的安装与配置 构 ...

最新文章

  1. SpringBoot 项目tomcat插件启动报错 java.lang.NoClassDefFoundError: javax/el/ELManager
  2. C 一个非递减数组 下标从0到n 元素的取值范围为从0到n的整数 判断其中是否有重复元素
  3. 说一说网站与搜索引擎之间不得不知的联系
  4. k8s部署dashboard
  5. mysql blob hex_数据库的完整备份与恢复 quot;--hex-blobquot; - - ITeye博客
  6. 3d打印主要的切片参数类型_3D打印机切片参数详情说明
  7. stk在计算机仿真中的应用_学习电路仿真:proteus电路仿真软件在ARM中的应用解析...
  8. javascript window.close() 去掉那讨厌的确认对话框【转】
  9. python能做什么-普通小白学会Python到底具体能做什么呢?
  10. java web 调度_javaweb车辆调度信息管理平台
  11. win7动态壁纸_电脑桌面美化,高清动态壁纸
  12. 存储器容量计算及相关概念
  13. aliez歌词_aLIEz (中文版)歌词 aLIEz (中文版)Lrc歌词
  14. 详解Instant类
  15. Centos(Linux)系统备份与还原
  16. 一些广州音字的输入方法
  17. 【正点原子Linux连载】第六十七章 Linux USB驱动实验 -摘自【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.0
  18. java 垃圾收集器_JVM垃圾收集器详解
  19. 宋词欣赏 李清照
  20. ensp 移动主机搜索不到AP信道_H3C H5套装评测,AC+AP无缝漫游

热门文章

  1. 100万并发连接服务器笔记之1M并发连接目标达成
  2. LeetCode 542 01 矩阵
  3. USACO-Section1.3 Palindromic Squares (进制转换和回文数)
  4. 1. OD-界面视图及基本快捷键操作,修改hello word
  5. 题解 P2949 【[USACO09OPEN]工作调度Work Scheduling】
  6. 解决VS2017引用报错问题
  7. char,short ,int ,long,long long,unsigned long long数据范围
  8. IaaS,PaaS,Saas 云服务的介绍
  9. matconvnet在ubuntu15.10下配置和使用方法
  10. QT消息,事件,槽的典型用法