Mysql数据库版本高低引起的group by问题
低版本的Mysql,group by限制性比较小,在进行group by时,select的对象可包含多个,但是换成高版本5.6以上好像,使用group by 以后,select的对象必须也已经被聚合,否则查询不出来数据,经百度资源,纳入解决方案如下:
查看sql_mode的值:
show variables like "sql_mode";
5.6版本的value值可能为:
value='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'
修改value值:
set sql_mode='NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES';
相似文章,掘金:MySQL:为什么查询列表中多了它,GROUP BY语句就会报错呢?
Mysql数据库版本高低引起的group by问题
事前准备(原文地址:https://juejin.im/post/5d64d704e51d45620b21c3f4)
先得建一个表:
CREATE TABLE student_score (
number INT(11) NOT NULL,
name VARCHAR(30) NOT NULL,
subject VARCHAR(30) NOT NULL,
score TINYINT(4) DEFAULT NULL,
PRIMARY KEY (number,subject)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
student_score,填充一些数据:
mysql> SELECT * FROM student_score;
+----------+-----------+-----------------------------+-------+
| number | name | subject | score |
+----------+-----------+-----------------------------+-------+
| 20180101 | 杜子腾 | 母猪的产后护理 | 78 |
| 20180101 | 杜子腾 | 论萨达姆的战争准备 | 88 |
| 20180102 | 杜琦燕 | 母猪的产后护理 | 100 |
| 20180102 | 杜琦燕 | 论萨达姆的战争准备 | 98 |
| 20180103 | 范统 | 母猪的产后护理 | 59 |
| 20180103 | 范统 | 论萨达姆的战争准备 | 61 |
| 20180104 | 史珍香 | 母猪的产后护理 | 55 |
| 20180104 | 史珍香 | 论萨达姆的战争准备 | 46 |
+----------+-----------+-----------------------------+-------+
8 rows in set (0.00 sec)
GROUP BY是在干什么?
MySQL提供了一系列的聚集函数,诸如:
- COUNT:统计记录数。
- MAX:查询某列的最大值。
- MIN:查询某列的最小值。
- SUM:某列数据的累加总和。
- AVG:某列数据的平均数。
查看student_score表中所有人成绩的平均数:
mysql> SELECT AVG(score) FROM student_score;
+------------+
| AVG(score) |
+------------+
| 73.1250 |
+------------+
1 row in set (0.00 sec)
查看《母猪的产后护理》这个科目的平均成绩,加个WHERE:
mysql> SELECT AVG(score) FROM student_score WHERE subject = '母猪的产后护理';
+------------+
| AVG(score) |
+------------+
| 73.0000 |
+------------+
1 row in set (0.00 sec)
单独查看《论萨达姆的战争准备》这门课程的平均成绩:
mysql> SELECT AVG(score) FROM student_score WHERE subject = '论萨达姆的战争准备';
+------------+
| AVG(score) |
+------------+
| 73.2500 |
+------------+
1 row in set (0.00 sec)
这时候问题来了,如果这个student_score表中存储了20门科目的成绩信息,那我们怎么单独的得到这20门课程的平均成绩呢?单独写20个查询语句?那要是有100门课呢?
很显然,不能傻兮兮的写一百个语句,设计MySQL的大叔给我们提供了分组的概念。我们可以按照某个列将表中的数据进行分组,比方说我们现在按照subject列对表中数据进行分组,那么所有的记录就会被分成2组,如图所示:
让MySQL产生这样子的分组的语句就是GROUP BY子句,我们只要在GROUP BY后边把需要分组的列写上就好,然后在查询列表处就可以针对每一个分组来写相应的聚集函数去统计该分组,就像这样:
mysql> SELECT subject, AVG(score) FROM student_score GROUP BY subject;
+-----------------------------+------------+
| subject | AVG(score) |
+-----------------------------+------------+
| 母猪的产后护理 | 73.0000 |
| 论萨达姆的战争准备 | 73.2500 |
+-----------------------------+------------+
2 rows in set (0.00 sec)
报错
可以从上边带有GROUP BY子句的查询语句中看出来,我们只在查询列表处放了分组列subject以及对该分组中的记录调用的聚集函数AVG,那如果我们把不是分组列的字段也放到查询列表中会出现啥情况:
mysql> SELECT subject, name, AVG(score) FROM student_score GROUP BY subject;
ERROR 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'dahaizi.student_score.name' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
mysql>
为啥会报错呢?回想一下我们使用GROUP BY子句的初衷,我们只是想把记录分为若干组,然后再对各个组分别调用聚集函数去做一些统计工作。本例中的查询列表处放置了既非分组列、又非聚集函数的name列,那我们想表达啥意思呢?从各个分组中的记录中取一个记录的name列?该取哪条记录为好呢?比方说对于’母猪的产后护理’这个分组中的记录来说,name列的值应该取杜子腾,还是杜琦燕,还是范统,还是史珍香呢?这个我们也不知道,所以把非分组列放到查询列表中会引起争议,导致结果不确定,所以设计MySQL的大叔才会为上述语句报错。
不过有的同学会说,假如分组后的某个分组的某个非分组列的值都一样,那我把该非分组列加入到查询列表中也没啥问题呀。比方说按照subject列进行分组后,假如在’母猪的产后护理’的分组中各条记录的name列的值都相同,在’论萨达姆的战争准备’的分组中各条记录的name列的值也都相同,那么我们把name列放在查询列表中也没啥问题。可能设计MySQL的大叔觉得这种说法也有点儿道理,他们竟然同意在一些情况下把非分组列也放到查询列表中,这就设计到一个称之为sql_mode的系统变量,我们先看一下在我的电脑上这个系统变量的值:
mysql> SHOW VARIABLES LIKE 'sql_mode';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.02 sec)
只关心其中一个称之为ONLY_FULL_GROUP_BY的家伙。只要sql_mode的值里边有这个东东,MySQL服务器就“比较正常”(也就是不允许非分组列放到查询列表中),但是如果我们把这个东东从sql_mode系统变量中移除(移除这个东东只要重新设置一下这个系统变量,把这个东东从值里边去除掉就好):
mysql> set sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Query OK, 0 rows affected (0.00 sec)
然后再执行上边那个曾经报错的语句:
mysql> SELECT subject, name, AVG(score) FROM student_score GROUP BY subject;
+-----------------------------+-----------+------------+
| subject | name | AVG(score) |
+-----------------------------+-----------+------------+
| 母猪的产后护理 | 杜子腾 | 73.0000 |
| 论萨达姆的战争准备 | 杜子腾 | 73.2500 |
+-----------------------------+-----------+------------+
2 rows in set (0.00 sec)
这回就不会报错了。
小贴士:
不同MySQL版本中sql_mode的值可能默认包含ONLY_FULL_GROUP_BY这个家伙,也可能不包含ONLY_FULL_GROUP_BY这个家伙,也就是说不同MySQL版本中可能默认不支持查询列表中包含非分组列,也可能默认支持查询列表中包含非分组列。
Mysql数据库版本高低引起的group by问题的更多相关文章
- 查看mysql数据库版本方法总结
当你接手某个mysql数据库管理时,首先你需要查看维护的mysql数据库版本:当开发人员问你mysql数据库版本时,而恰好你又遗忘了,那么此时也需要去查看mysql数据库的版本............ ...
- MySQL JDBC驱动版本与MySQL数据库版本对应关系
前言:前段时间发现在家使用和公司一样的mysql jdbc驱动版本发生了异常,原因:家里mysql数据库版本与公司不一致导致.查询了相关资料,发现mysql jdbc驱动版本与mysql数据库版本有一 ...
- CentOS6.8下MySQL数据库版本信息查看
方法1:使用mysql -v命令查看: [root@yeebian mysql]# mysql -V mysql Ver 14.14 Distrib 5.1.73, for redhat-linux- ...
- dinner 后台 nodemon 部署 Koa (关闭everything 安装或排除node_modules) # mysql 没开192.168.x.x 需要设置一下 #Navicat Premium,mysql 数据库版本有要求:mysql-5.7.17.msi 对??的支持
tip1:新建数据库 记得选 字符集和排序规则 utf8 -- UTF-8 Unicode utf8_general_ci 后台链接部分 1. 全局管理员安装 nodemon,后台热部署(右键 管理员 ...
- 详解PhpStudy集成环境升级MySQL数据库版本
http://phpstudy.php.cn/jishu-php-2967.html phpstudy里没有地方可以设置mysql数据库,很多人都疑惑在phpstudy里怎么升级mysql数据库版本, ...
- 三种查看MySQL数据库版本的方法
https://blog.csdn.net/hj7jay/article/details/51921504 1.使用-V参数 首先我们想到的肯定就是查看版本号的参数命令,参数为-V(大写字母)或者-- ...
- 查看Mysql数据库版本
一.使用终端 1.参数为-V(大写字母)或者--version 使用方法: D:\mysql\bin>mysql -V 或者 D:\mysql\bin>mysql --version
- mysql数据库版本引发的问题
改前: 改后:
- 用Navicat Premium快速查看mysql数据库版本信息
在出现的界面输入命令 select version();
随机推荐
- hive集群模式安装
hadoop3.2.0 完全分布式安装 hive-3.1.1 #解压缩tar -zxvf /usr/local/soft/apache-hive-3.1.1-bin.tar.gz -C /usr/lo ...
- Access-Control-Allow-Headers等基础常识
跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种机制,该机制使用附加的 HTTP 头来告诉浏览器,准许运行在一个源上的Web应用访问位于另一不同源选定的资源. 当一个Web应用发起一个与 ...
- JVM个人总结一
看了深入理解JAVA虚拟机已经有一段时间了 发现很多东西如果不总结 脑子里总是没有一条线贯穿起来,也比较模糊混乱,所以还是有必要利用逻辑思维图总结下. JVM看了下 大致比较重要的分内存区域划分 ...
- Thread.join详解
/** * 如果某个线程在另一个线程t上调用t.join:那么此线程将被挂起,直到目标t线程的结束才恢复即t.isAlive返回为假 * * @date:2018年6月27日 * @author:zh ...
- javascript 匿名函数的理解(转)
原网址 http://www.jb51.net/article/21948.htm javascript 匿名函数的理解(透彻版) 代码如下: (function(){ //这里忽略jQuery所有实 ...
- netcore项目中使用 SpringCloudConfig 和apollo做配置中心
版权所有,转载请注明出处 https://www.cnblogs.com/netqq/p/14251403.html 一.使用apollo作为配置中心 首先apollo 项目简介和安装请自行百度,本文 ...
- instanceof和isInstance的区别
instanceof 是一个操作符(类似new, ==等) ( Object reference variable ) instanceof (class/interface type) if(a i ...
- IE浏览器F12无法使用
原文链接http://zhhll.icu/2020/04/07/windows/IE%E6%B5%8F%E8%A7%88%E5%99%A8F12%E6%97%A0%E6%B3%95%E4%BD%BF% ...
- 使用vs code搭建Q#开发环境 (Mac)
Q# 是微软几年前发布的一门用于模拟量子编程的语言. 3年前我在当时风靡的博客网站 ITEYE 上发布过如何在windows上搭建其开发环境:Q#开发环境搭建.时过境迁,不但iteye不知何处去,连Q ...
- aix5.3安装httpd服务
1.安装gcc(1)从IBM上下载 gcc-4.0.0-1.aix5.3.ppc.rpm gcc-cplusplus-4.0.0-1.aix5.3.ppc.rpm libgcc-4.0.0-1.aix ...