前言  

  在一次使用group by查询数据库时,遇到了问题。下面先搭建环境,然后让问题复现,最后分析问题。

一 问题复现

  mysql版本

  

  建表插入数据

  

  表的结构

  

  现在问题来了:我想查询上面表中每个部门年龄最大的人。

  sql语句:select NAME,dept,MAX(age) from mytable group by dept;

  

  此时会发现:查询结果中,dept 和 max(age) 是正确的,但是name却是错误的!!!因为34岁的101部门应该指向 li4 ,36岁的102部门应该是 tian7。

二 分析原因

  对于上面的问题主要要注意两个方面:

  1.为什么很多网上的帖子会出现这个sql语句查询报错的情况?

  2.为什么这种sql语句能执行但是查询结果不正确?

  

  下面针对这两个方面进行展开说明:

  1.

    有很多人可能使用上面的sql语句查询会报错,抛出这样的错误

    

    翻译过来就是:select list的表达式1不在group by子句中,并且包含非聚合列“test.mytable.name”,该列在功能上不依赖于group by子句中的列;这与sql _mode=only_full _group _by不兼容

    既然这里提到了sql_mode,那我就来查查sql_mode,如果你抛出了上面的错误,那么你的sql_mode中一定包含 ONLY_FULL_GROUP_BY

    show variables like 'sql_mode';

    

    什么是sql_mode?

    官方解释:

      The MySQL server can operate in different SQL modes, and can apply these modes differently for different clients, depending on the value of the sql_mode system variable. DBAs can set the     global SQL mode to match site server operating requirements, and each application can set its session SQL mode to its own requirements

    中文翻译:

      mysql服务器可以在不同的SQL模式下运行,并且可以根据sql_模式系统变量的值,为不同的客户机应用这些模式。DBA可以设置全局SQL模式以匹配站点服务器操作需求,并且每个应用程序        都可以将其会话SQL模式设置为自己的需求。

    同时:

      sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,比如允许一些非法数据的插入。在生产环境必须将这个值设置为严格模式,所以开发、测试环境       的数据库也必须要设置,这样在开发测试阶段就可以发现问题。

    在我们使用group by进行查询语句时,如果查询字段不在聚合列中(也就是group by后面的列),实际上这种sql语句是错误的,也是没有意义的,mysql是可以不支持这种查询方式的。在我们生产环      境中,最好将sql_mode设置为严格模式,这样在开发阶段就能发现问题,排除错误、无效的sql语句。

    ONLY_FULL_GROUP_BY就是规定了你不能使用错误、无效的group by去查询数据,所以,如果你的sql_mode是ONLY_FULL_GROUP_BY,那么执行上面那条sql语句就会抛出错误了。

  2.

    那为什么我使用上面的sql语句查询时,没有抛出错误,自然也就得到了解释,因为我当时的sql_mode 是这样的:

    

    并不包含ONLY_FULL_GROUP_BY,同时,我们看到的查询结果是错误的,这也从反面说明了 mysql规定的一些sql_mode的必要性,就是因为某些sql语句会出现问题,但是又不能及时被发现。所以     在开发环境中,使用合适的严格的sql_mode 至关重要。

三 有哪些sql_mode?

  官方说明先放在这: https://dev.mysql.com/doc/refman/5.6/en/sql-mode.html

  简单介绍如下:

  ONLY_FULL_GROUP_BY:
  对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中

  NO_AUTO_VALUE_ON_ZERO:
  该值影响自增长列的插入。默认设置下,插入0或NULL代表生成下一个自增长值。如果用户 希望插入的值为0,而该列又是自增长的,那么这个选项就有用了。

  STRICT_TRANS_TABLES:
  在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制

  NO_ZERO_IN_DATE:
  在严格模式下,不允许日期和月份为零

  NO_ZERO_DATE:
  设置该值,mysql数据库不允许插入零日期,插入零日期会抛出错误而不是警告。

  ERROR_FOR_DIVISION_BY_ZERO:
  在INSERT或UPDATE过程中,如果数据被零除,则产生错误而非警告。如 果未给出该模式,那么数据被零除时MySQL返回NULL

  NO_AUTO_CREATE_USER:
  禁止GRANT创建密码为空的用户

  NO_ENGINE_SUBSTITUTION:
  如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

  PIPES_AS_CONCAT:
  将"||"视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似

  ANSI_QUOTES:
  启用ANSI_QUOTES后,不能用双引号来引用字符串,因为它被解释为识别符

四 如何设置sql_mode

  sql_mode的设置分为局部(session)设置和全局(global)设置 下面是我从mysql官网直接拿过来的:

  session就是指 你设置的sql_mode只会在你当前会话有效,当你注销用户,重新登录mysql后,仍然是你默认的sql_mode

  global就是指全局的。

  设置GLOBAL变量需要该SUPER权限,并影响从该时间开始连接的所有客户端的操作。设置SESSION变量仅影响当前客户端。每个客户端都可以随时更改其会话sql_mode值

  

  另外的一种设置方式:

  直接修改mysql配置文件,打开mysql配置文件可以看到:

  

  这个sql_mode也就是我默认的,也可以在此处修改。

  最后多说一点,虽然mysql规定了这么多sql_mode用来约束sql语句规范,但是并不是每一个sql_mode都要配上,我们要在合适的环境选择合适的配置

另,原创,转载注明出处!

      

由group by引发的sql_mode的学习的更多相关文章

  1. 由SecureCRT引发的思考和学习

    由SecureCRT引发的思考和学习 http://mp.weixin.qq.com/s?__biz=MzAxOTAzMDEwMA==&mid=2652500597&idx=1& ...

  2. 由简单的CMD命令引发的一场学习战斗

    想要打开一个软件时,由于桌面没有存放快捷方式,又忘了软件存放在电脑上的哪个角落.脑海里突然闪过一个想法:用CMD自定义软件的打开方式,于是问了度娘.由此,引发了一场停不下来的CMD学习战斗. 爱上CM ...

  3. js 一道题目引发的正则的学习

    正则表达式中的特殊字符 字符 含意 \ 做为转意,即通常在"\"后面的字符不按原来意义解释,如/b/匹配字符"b",当b前面加了反斜杆后/\b/,转意为匹配一个 ...

  4. [转]如何正确学习JavaScript

    原文:How to Learn JavaScript Properly(2014-2-7) 学习时长:6-8周 学习前提:中学水平,无需编程经验 更新(2014-1-7) 在Reddit上创建了一个学 ...

  5. 不用写代码就能实现深度学习?手把手教你用英伟达 DIGITS 解决图像分类问题

    2006年,机器学习界泰斗Hinton,在Science上发表了一篇使用深度神经网络进行维数约简的论文 ,自此,神经网络再次走进人们的视野,进而引发了一场深度学习革命.深度学习之所以如此受关注,是因为 ...

  6. 理解一条语句:SELECT difference(sum("value")) FROM "mq_enqueue" WHERE "channel" =~ /ActiveMQ_TEST/ AND $timeFilter GROUP BY time($interval)

    最近使用grafana在查询InfluxDB中,用到了这一条语句 SELECT difference(sum("value")) FROM "mq_enqueue&quo ...

  7. 【目录】Spring 源码学习

    [目录]Spring 源码学习 jwfy 关注 2018.01.31 19:57* 字数 896 阅读 152评论 0喜欢 9 用来记录自己学习spring源码的一些心得和体会以及相关功能的实现原理, ...

  8. linux初级学习笔记六:linux用户及权限详解!(视频序号:03_4)

    本节学习的命令:/etc/passwd,/etc/shadow,/etc/group文件详解 本节学习的技能: 安全上下文 文件与目录的权限管理 影子命令 用户,用户组类别详解 /etc/passwd ...

  9. KNN学习笔记

    简单地说,KNN算法就是通过测量不同特征值之间的距离来对特征进行分类的一种算法. 优点:精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. 工 ...

随机推荐

  1. 【dfs基础讲解及例题】

    定义 DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种. 接下来因为懒得去找大段大段深奥的材料 所以就是一些个人的理解. 所谓深搜,是相对于广搜(只是第一篇)来说的.深 ...

  2. re模块:模式匹配与正则表达式

    一.用正则表达式查找文本模式 正则表达式,简称regex,是文本模式的描述方法.比如\d是一个正则表达式,用于表示一位0~9的数字.在一个模式后面加上花括号包围的数字n(如{n}),表示匹配这个模式n ...

  3. 小埋的Dancing Line之旅:比赛题解&热身题题解

    答疑帖: 赞助团队:UMR IT Team和洛谷大佬栖息地 赛后题解:更新了那两道练手题的题解 赛时公告,不过一些通知也可能在团队宣言里发出 如果各位发现重题,请将你认为重复的题目链接连同这次比赛的题 ...

  4. java.util.LinkedHashMap cannot be cast to

    Jackson转换泛型List出现错误java.util.LinkedHashMap cannot be cast to com.xxx ObjectMapper mapper = new Objec ...

  5. 新手小白之学习python一飞冲天日志之—基本数据类型,条件控制语句

    python的历史 04年目前最流行的WEB框架Django诞生 python2:源码不统一,有重复的功能代码 python3:源码统一,没有重复的功能代码 python是一个什么编程语言 编译型:编 ...

  6. http面试笔试常考知识点(一)

    1.什么是http HTTP是客户端和服务器端请求和应答的标准.通过使用Web浏览器.网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求.(我们称这个客户端)叫用 ...

  7. C#写好的类库dll在别人调用的时候也能看到注释的方法

    1.用///的方法添加注释 2.项目的属性里面,要选上"生成XML注释文档" 菜单 Project -> 'xxxx' Properties -> Build -> ...

  8. 从零开发一款自己的小程序UI组件库(一)

    写在前面:有开发过小程序的朋友肯定知道组件化开发的特性,高内聚与低耦合.使用已有的UI组件库,诸如:vantUI-weapp.minUI-weapp等UI组件库的诞生使我们的开发速度大大的加快,丰富的 ...

  9. 172. 阶乘后的零 Java解法

    https://leetcode-cn.com/problems/factorial-trailing-zeroes/ 172. 阶乘后的零 这题要完成其实要知道一个很巧妙的思想,就是阶乘里面,后面的 ...

  10. 【JDK】JDK源码分析-List, Iterator, ListIterator

    List 是最常用的容器之一.之前提到过,分析源码时,优先分析接口的源码,因此这里先从 List 接口分析.List 方法列表如下: 由于上文「JDK源码分析-Collection」已对 Collec ...