低版本的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语句就会报错呢?

事前准备(原文地址: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问题的更多相关文章

  1. 查看mysql数据库版本方法总结

    当你接手某个mysql数据库管理时,首先你需要查看维护的mysql数据库版本:当开发人员问你mysql数据库版本时,而恰好你又遗忘了,那么此时也需要去查看mysql数据库的版本............ ...

  2. MySQL JDBC驱动版本与MySQL数据库版本对应关系

    前言:前段时间发现在家使用和公司一样的mysql jdbc驱动版本发生了异常,原因:家里mysql数据库版本与公司不一致导致.查询了相关资料,发现mysql jdbc驱动版本与mysql数据库版本有一 ...

  3. CentOS6.8下MySQL数据库版本信息查看

    方法1:使用mysql -v命令查看: [root@yeebian mysql]# mysql -V mysql Ver 14.14 Distrib 5.1.73, for redhat-linux- ...

  4. 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,后台热部署(右键 管理员 ...

  5. 详解PhpStudy集成环境升级MySQL数据库版本

    http://phpstudy.php.cn/jishu-php-2967.html phpstudy里没有地方可以设置mysql数据库,很多人都疑惑在phpstudy里怎么升级mysql数据库版本, ...

  6. 三种查看MySQL数据库版本的方法

    https://blog.csdn.net/hj7jay/article/details/51921504 1.使用-V参数 首先我们想到的肯定就是查看版本号的参数命令,参数为-V(大写字母)或者-- ...

  7. 查看Mysql数据库版本

    一.使用终端 1.参数为-V(大写字母)或者--version 使用方法: D:\mysql\bin>mysql -V 或者 D:\mysql\bin>mysql --version

  8. mysql数据库版本引发的问题

    改前: 改后:

  9. 用Navicat Premium快速查看mysql数据库版本信息

    在出现的界面输入命令  select version();

随机推荐

  1. 超级电容(Supercapacitor) 和电池的比较

    之前看到同事在电路设计里使用了超级电容来进行供电,好奇为什么没有用到普通的电池,于是就是找了找两个的区别.有篇文章讲得挺好,所以就直接翻译一下. 超级电容有点像普通电池和一般电容的结合体,能比一般的电 ...

  2. Erlang那些事儿第3回之我是函数(fun),万物之源MFA

    Erlang代码到处都是模式匹配,这把屠龙刀可是Erlang的看家本领.独家绝学,之前在<Erlang那些事儿第1回之我是变量,一次赋值永不改变>文章提到过,Erlang一切皆是模式匹配. ...

  3. 设计模式之SOLID原则

    介绍 设计模式中的SOLID原则,分别是单一原则.开闭原则.里氏替换原则.接口隔离原则.依赖倒置原则.前辈们总结出来的,遵循五大原则可以使程序解决紧耦合,更加健壮. SRP 单一责任原则 OCP 开放 ...

  4. .NET的并发编程(TPL编程)是什么?

    写在前面 优秀软件的一个关键特征就是具有并发性.过去的几十年,我们可以进行并发编程,但是难度很大.以前,并发性软件的编写.调试和维护都很难,这导致很多开发人员为图省事放弃了并发编程.新版 .NET 中 ...

  5. 【转】借助LVS+Keepalived实现负载均衡

    一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务 ...

  6. Docker-ce Centos8 笔记二:常见问题

  7. HBase 底层原理详解(深度好文,建议收藏)

    HBase简介 HBase 是一个分布式的.面向列的开源数据库.建立在 HDFS 之上.Hbase的名字的来源是 Hadoop database,即 Hadoop 数据库.HBase 的计算和存储能力 ...

  8. nginx文件结构与解析,例子

    1.nginx文件结构 1 ... #全局块 2 3 events { #events块 4 ... 5 } 6 7 http #http块 8 { 9 ... #http全局块 10 server ...

  9. 关于软件架构中的b/s

    **B/S架构 b/s只需要一个浏览器,用户就可以通过不同的网址访问不同的服务器程序. 优点:开发,安装,部署,维护简单 缺点:对硬件要求过高,用户的体验会受到影响 首先是资源分类:**可以分为静态资 ...

  10. ThinkPHP5表单令牌刷新

    制作登录页面的时候,加入了表单令牌,账号和密码输入错误后,再登录的话,会提示表单令牌错误, 这是因为旧的令牌已经过期了,我们要处理下前端的token,修复的办法,在路由文件下加入 //刷新表单令牌,然 ...