问题背景

最近在项目中使用mysql的group by进行分组查询的场景比较多,其中一次遇到了一个问题,即在开发环境执行一个如下sql时是正确且可执行的,

select a,b,max(c) from test_tbl group by a

但是放到了测试环境就会报如下的错误。

[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column 'your_tbl...' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

解决办法

因为开发环境和测试环境所使用的mysql数据库的版本不一样,开发环境使用的时候5.6.x而测试环境使用的是5.7.x,而在Mysql的5.7.x版本中默认是开启sql_mode = only_full_group_by
而在这个模式下,我们使用分组查询时,出现在select字段后面的只能是group by后面的分组字段,或使用聚合函数包裹着的字段。
在上面的sql中,字段b既不是group by里面的分组字段,也没有被聚合函数包裹着。5.7以下的版本不进行检查,而5.7以上的版本进行了sql_mode=only_full_group_by的检查,所以会出现以上的问题,当然解决方法也很简单,将b也纳入到分组字段中即可。

group by深入思考

虽然在工作中会频繁的使用到group by进行分组查询,但自己对数据分组这个概念一直很模糊,这次就借着这个机会,通过一个简单的示例来帮助大家在脑海中建立起来数据分组这个抽象概念。

我们创建一张如下的数据表

CREATE TABLE `product` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`product_name` varchar(100) NOT NULL COMMENT '商品名称',
`brand_name` varchar(100) DEFAULT NULL COMMENT '品牌名称',
`category_name` varchar(100) NOT NULL COMMENT '商品分类',
`price` decimal(10,4) NOT NULL COMMENT '价格'
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='测试用的商品表';

表中有如下数据

mysql> select * from product;
+----+---------------+------------+---------------+-------+
| id | product_name | brand_name | category_name | price |
+----+---------------+------------+---------------+-------+
| 1 | XiaoMi6X | XiaoMi | 手机 | 2999 |
| 2 | XiaoAi | Lenovo | 电脑 | 8999 |
| 3 | HUAWEI K1 | HUAWEI | 手机 | 1999 |
| 4 | iPhone X | iPhone | 手机 | 9999 |
| 5 | MacBook Pro | Mac | 电脑 | 13999 |
| 6 | iPhone XMAX | iPhone | 手机 | 10999 |
| 7 | HUAWEI Mate20 | HUAWEI | 手机 | 2999 |
+----+---------------+------------+---------------+-------+
7 rows in set

一个最高价

我们使用group by按照品牌类目(category_name)进行分组,并获取该分组中的最高价格。

mysql> select category_name,max(price) from product group by category_name;
+---------------+------------+
| category_name | max(price) |
+---------------+------------+
| 手机 | 10999 |
| 电脑 | 13999 |
+---------------+------------+
2 rows in set

这个简单的分组sql相信也难不倒大家,那么让我们来看看这个分组查询语句是如何取到最终结果的。

过程:如下图所示,首先从数据集中筛选出来类目为手机的所有记录(以蓝色线框标明)和类目为电脑的所有记录(以红色线框标明)并将这些记录归集到一起,那么分组之后就出现了以不同类目进行划分的两个数据集,然后再从各自的数据集中选出最高的价格便可得到最终的结果。

一个最低价

再举一个例子,我们用品牌名称brand_name进行分组,并使用聚合函数算出该品牌下的最低价格。

mysql> select brand_name,min(price) from product group by brand_name;
+------------+------------+
| brand_name | min(price) |
+------------+------------+
| HUAWEI | 1999 |
| iPhone | 9999 |
| Lenovo | 8999 |
| Mac | 13999 |
| XiaoMi | 2999 |
+------------+------------+
5 rows in set

过程:如下图所示,从数据集中按照品牌名称brand_name进行分组,然后按照品牌名称就筛选出了一共五组品牌,然后再从各自品牌中选出最低价格便可得到最终结果。

后记总结

取经归来后,愈发的觉得无论生活还是技术都应该持有一种脱离表层、向往深层的探索追求精神,在这个过程中我会不断的总结分享,与诸君共勉! 

only_full_group_by问题而引发的对group by的深入思考的更多相关文章

  1. 由linux下的多进程编程引发的关于进程间隔离的思考

    源代码放到了三个文件中: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include & ...

  2. 由html,body{height:100%}引发的对html和body的思考

    html,body{height:100%} 今天看到一个CSS样式:html,body{height:100%},第一次看到,感觉挺奇怪,为什么html还需要设置height:100%呢,html不 ...

  3. 从一个小例子引发的Java内存可见性的简单思考和猜想以及DCL单例模式中的volatile的核心作用

    环境 OS Win10 CPU 4核8线程 IDE IntelliJ IDEA 2019.3 JDK 1.8 -server模式 场景 最初的代码 一个线程A根据flag的值执行死循环,另一个线程B只 ...

  4. 关于Mysql5.7高版本group by新特性报错

    一个项目的开发到测试上线运营,团队对项目的管理不成熟会影响项目的开发效率.由于项目是我刚接手,独自在Centos搭建PHP环境,所以就考虑使用高版本,选择了Mysql5.7,本地开发环境还是Windo ...

  5. mysql5.7.X版本only_full_group_by问题解决

    一.出错原因 最近因为开发数据库与部署数据库版本不同,带来了几个问题,其中only_full_group_by问题是之前没有遇到的. 具体报错如下 [Err] 1055 - Expression #1 ...

  6. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: ..... this is incompatible with sql_mode=only_full_group_by

    一.异常信息 org.springframework.jdbc.BadSqlGrammarException: ### Error querying database. Cause: com.mysq ...

  7. mysql only_full_group_by报错的问题(转)

    原文:https://www.cnblogs.com/jim2016/p/6322703.html 在mysql 工具 搜索或者插入数据时报下面错误: ERROR 1055 (42000): Expr ...

  8. !!!sql_mode=only_full_group_by配置

    Expression #7 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'invoicecer ...

  9. mysql命令gruop by报错this is incompatible with sql_mode=only_full_group_by

    在mysql 工具 搜索或者插入数据时报下面错误: ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause ...

随机推荐

  1. 跟bWAPP学WEB安全(PHP代码)--PHP代码注入

    ---恢复内容开始--- 背景 今天我们换一个方式来分析这个漏洞,从渗透的角度去搞. 渗透过程 测试漏洞 先来看看,观察URL是:http://192.168.195.195/bWAPP/phpi.p ...

  2. linux的shell后门尝试以及Cython转成C代码编译

    零.背景 最近研究了一下之前的反弹shell的python代码块,写了一点代码尝试在LInux下绑定和反弹shell(正反向),看了一些代码,基本是两种思路.1.本地shell的输入输出通过管道与so ...

  3. Thinkphp框架下对某个字段查询数据的时候进行唯一过滤,返回唯一不同的值

    方法一. DISTINCT 方法用于返回唯一不同的值 . *distinct方法的参数是一个布尔值. 用法: $data = $Model->Distinct(true)->field(' ...

  4. nginx socket转发设置

    1.添加依赖模块,如下 --with-stream --with-stream_ssl_module 2.nginx.conf 配置,参考说明:ngx_stream_core_module user ...

  5. mysql判断一个字符串是否包含某几个字符

    使用locate(substr,str)函数,如果包含,返回>0的数,否则返回0

  6. 获取页面所有链接的JS

    写了一个实用的JS脚本,获取当前页面所有的JS: var str = " \n"; var list = document.getElementsByTagName("a ...

  7. Linux--抓取Appium网站命令

    # 获取各命令url地址 curl http://appium.io/docs/en/commands/device/app/is-app-installed/ 2>/dev/null | gr ...

  8. js备忘录_1

    js没有重载,只有同名覆盖,参数任意 所有参数封装在arguments数组中 Uncaught ReferenceError: d is not defined js引擎会当做变量处理 functio ...

  9. Asp.net中的web.config配置

    目录 Asp.net中的web.config配置... 1 一. 配置文件保存位置... 2 二. 配置文件加载顺序... 2 三. 配置文件节点介绍... 3 1. . 3 2. . 5 3. . ...

  10. CCCC 月饼

    https://www.patest.cn/contests/gplt/L2-003 题解:按平均值贪心. 坑:有一个样例卡住了,是因为 while (i<=n&&x - bs[ ...