前言  

  在一次使用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. WinForm控件之【MonthCalendar】

    基本介绍 日期月历控件,顾名思义用来主要用来展示月历,获取年份.月份.日期.时分秒信息等 常设置属性 FirstDayOfWeek:面板展示周期的循序,一周的第一天由从周几开始排列: MaxDate: ...

  2. 获取文件版本(IE)

    GetFileInfoCUIAction::GetFileVersion2GetSystemDirectory     WCHAR szConfigFile[MAX_PATH + 1];    ::G ...

  3. dubbo框架设计学习

    1.整体设计 (1)架构图 图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单向依赖,右 ...

  4. 个人永久性免费-Excel催化剂功能第105波-批量调整不规范的图形对象到单一单元格内存储

    在日常制表过程中,一个不得不面对的问题,许多的工作起点是基于其他人加工过的表格,无论自己多大的本领,面对不规范的其他人的制作的表格,经过自己的手,该擦的屁股还是要自己去亲手去擦,而带出来的也只会是一堆 ...

  5. Excel催化剂图表系列之品味IBCS瀑布图观察企业利润构成

    IBCS图表,每个细节都值得反复琢磨参悟,此篇给大家送上详尽的瀑布图方式下的利润数据观察.请不要拿Excel2016版提供的瀑布图与IBCS版的瀑布图作对比,那完全不是一个级别的,可以类比为拿一辆经济 ...

  6. Mysql 时间相关

    -- 当前时间SELECT NOW(), SYSDATE(), CURRENT_TIMESTAMP(), LOCALTIME(), LOCALTIMESTAMP();SELECT CURDATE(), ...

  7. Django REST Framework(DRF)_第二篇

    视图和路由 视图封装 第一次封装 ​ 上一篇最后我们对书籍表做了增删改查,那么如果现在我们有几十上百张表需要这样做呢?我们知道类的特性有封装,因此我们可以尝试进行封装下. from rest_fram ...

  8. JSP数据交互(一)

    1.JSP内置对象:JSP内置对象是 Web 容器创建的一组对象,不用通过手动new就可以使用 2.JSP9大内置对象:      对象名称 类型 request (请求对象) javax.servl ...

  9. PHP与ECMAScript_5_常用数组相关函数

    PHP ECMAScript 长度 $length = count($array) length = array.length       增 array_unshift($array, new1,n ...

  10. IDEA下基于MAVEN的SSM框架整合

    源码可以以上传github https://github.com/ingxx/ssm_first 最近把用IDEA把SSM框架整合一遍遇到了不少坑,在这里写出来 这里maven我使用的是自己下载的3. ...