本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/having_without_groupby_in_mysql.html 今天有同学给我反应,有一张表,id是主键,这样的写法可以返回一条记

本文内容遵从CC版权协议, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: http://www.penglixun.com/tech/database/having_without_groupby_in_mysql.html

今天有同学给我反应,有一张表,id是主键,这样的写法可以返回一条记录:

“SELECT * FROM t HAVING id=MIN(id);”

但是只是把MIN换成MAX,这样返回就是空了:

“SELECT * FROM t HAVING id=MAX(id);”

这是为什么呢?

我们先来做个试验,验证这种情况。

这是表结构,初始化两条记录,然后试验:

root@localhost : plx 10:25:10> show create table t2\G

*************************** 1. row ***************************

Table: t2

Create Table: CREATE TABLE `t2` (

`a` int(11) DEFAULT NULL,

`id` int(10) unsigned NOT NULL AUTO_INCREMENT,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

root@localhost : plx 10:25:15> select * from t2;

+------+----+

| a | id |

+------+----+

| 1 | 1 |

| 1 | 3 |

+------+----+

rows in set (0.00 sec)

root@localhost : plx 10:25:20> SELECT * FROM t2 HAVING id=MIN(id);

+------+----+

| a | id |

+------+----+

| 1 | 1 |

+------+----+

row in set (0.00 sec)

root@localhost : plx 10:25:30> SELECT * FROM t2 HAVING id=MAX(id);

Empty set (0.00 sec)

初看之下,好像真的是这样哎,怎么会这样呢?

我再试一下,把a字段改一个为10,然后试下a字段:

root@localhost : plx 10:26:58> select * from t2;

+------+----+

| a | id |

+------+----+

| 10 | 1 |

| 1 | 3 |

+------+----+

rows in set (0.00 sec)

root@localhost : plx 10:28:20> SELECT * FROM t2 HAVING a=MAX(a);

+------+----+

| a | id |

+------+----+

| 10 | 1 |

+------+----+

row in set (0.00 sec)

root@localhost : plx 10:28:28> SELECT * FROM t2 HAVING a=MIN(a);

Empty set (0.00 sec)

我擦,这回MAX能返回,MIN不能了,这又是为啥呢?

旁白

一般来说,HAVING子句是配合GROUP BY使用的,单独使用HAVING本身是不符合规范的,

但是MySQL会做一个重写,加上一个GROUP BY NULL,”SELECT * FROM t HAVING id=MIN(id)”会被重写为”SELECT * FROM t GROUP BY NULL HAVING id=MIN(id)”,这样语法就符合规范了。

继续……

但是,这个 GROUP BY NULL 会产生什么结果呢?经过查看代码和试验,可以证明,GROUP BY NULL 等价于 LIMIT 1:

root@localhost : plx 10:25:48> SELECT * FROM t2 GROUP BY NULL;

+------+----+

| a | id |

+------+----+

| 10 | 1 |

+------+----+

row in set (0.00 sec)

也就是说,GROUP BY NULL 以后,只会有一个分组,里面就是第一行数据。

但是如果这样,MIN、MAX结果应该是一致的,那也不应该MAX和MIN一个有结果,一个没结果啊,这是为什么呢,再做一个测试。

修改一下数据,然后直接查看MIN/MAX的值:

root@localhost : plx 10:26:58> select * from t2;

+------+----+

| a | id |

+------+----+

| 10 | 1 |

| 1 | 3 |

+------+----+

rows in set (0.00 sec)

root@localhost : plx 10:27:04> SELECT * FROM t2 GROUP BY NULL;

+------+----+

| a | id |

+------+----+

| 10 | 1 |

+------+----+

row in set (0.00 sec)

root@localhost : plx 10:30:21> SELECT MAX(a),MIN(a),MAX(id),MIN(id) FROM t2 GROUP BY NULL;

+--------+--------+---------+---------+

| MAX(a) | MIN(a) | MAX(id) | MIN(id) |

+--------+--------+---------+---------+

| 10 | 1 | 3 | 1 |

+--------+--------+---------+---------+

row in set (0.00 sec)

是不是发现问题了?

MAX/MIN函数取值是全局的,而不是LIMIT 1这个分组内的。

因此,当GROUP BY NULL的时候,MAX/MIN函数是取所有数据里的最大和最小值!

所以啊,”SELECT * FROM t HAVING id=MIN(id)”本质上是”SELECT * FROM t HAVING id=1″, 就能返回一条记录,而”SELECT * FROM t HAVING id=MAX(id)”本质上是”SELECT * FROM t HAVING id=3″,当然没有返回记录,这就是问题的根源。

测试一下GROUP BY a,这样就对了,每个分组内只有一行,所以MAX/MIN一样大,这回是取得组内最大和最小值。

root@localhost : plx 11:29:49> SELECT MAX(a),MIN(a),MAX(id),MIN(id) FROM t2 GROUP BY a;

+--------+--------+---------+---------+

| MAX(a) | MIN(a) | MAX(id) | MIN(id) |

+--------+--------+---------+---------+

| 1 | 1 | 3 | 3 |

| 10 | 10 | 5 | 5 |

+--------+--------+---------+---------+

rows in set (0.00 sec)

GROUP BY NULL时MAX/MIN的行为,是这个问题的本质,所以啊,尽量使用标准语法,玩花样SQL之前,一定要搞清楚它的行为是否与理解的一致。

Enjoy MySQL!

本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

本文系统来源:php中文网

mysql having in_MySQL中无GROUPBY直接HAVING的问题相关推荐

  1. mysql orderby count_mysql中count(),groupby,orderby使用方法分享

    本文主要和大家分享mysql中count(), group by, order by使用方法,mysql中order by 排序查询.asc升序.desc降序,group by 分组查询.having ...

  2. IDEA连接mysql后,schemas中无表格

    IDEA连接mysql后,schemas中无表格 例如: 建议: 可以重启idea试试(记得先Apply,如果还没有)

  3. mysql有符号和无符号,MySQL中的“无符号”是什么意思以及何时使用它?

    MySQL中的"无符号"是一种数据类型.每当我们在任何列中写入无符号表示您不能插入负数时.假设对于很大的数字,您可以使用无符号类型. 无符号整数的最大范围是4294967295.N ...

  4. MySQL 5.7中的更多改进,包括计算列

    让我们继续上一周的内容,讨论MySQL 5.7中的新特性,我们将把注意力集中于新的安全方面的特性.首先,新版本中取消了mysql_old_password这个认证插件.其实这个插件从版本4.x开始就已 ...

  5. mysql 互斥_MySql中互斥量mutex的实现

    数据库中的Mutex量指的是一种用于保护一些临界资源的使用的信号量.当有线程需要使用这些临界资源时,会请求获得mutex量,请求成功的线程进入临界区,而请求失败的线程只能等待它释放这个mutex.互斥 ...

  6. MySQL存储引擎中MyISAM和InnoDB区别

    转载自  MySQL存储引擎中MyISAM和InnoDB区别 MyISAM 和InnoDB 讲解 InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应 ...

  7. mysql select @x_mysql中select * for update

    由于InnoDB预设是Row-Level Lock,所以只有「明确」的指定主键,MySQL才会执行Row lock (只锁住被选取的资料例) ,否则MySQL将会执行Table Lock (将整个资料 ...

  8. mysql8.0源代码解析_源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统

    原标题:源码解读:MySQL 8.0 InnoDB无锁化设计的日志系统 作者介绍 张永翔,现任网易云RDS开发,持续关注MySQL及数据库运维领域,擅长MySQL运维,知乎ID:雁南归. MySQL ...

  9. Python中的groupby分组

    Python中的groupby分组 一.groupby函数 groupby函数功能:对DataFrame进行分组(可单类分组,可多类分组) 需求:按"字段"列对数据data进行分组 ...

最新文章

  1. 使用PHP CURL的POST数据
  2. 【深度学习】在PyTorch中构建高效的自定义数据集
  3. 简述dijkstra算法原理_Dijkstra算法之 Java详解
  4. Java 数据库进度条_java进度条
  5. 如何实现rtsp h265 转 rtmp (rtsp hevc 转 rtmp)并转发到CDN或自建服务器
  6. 语音交互有哪些优势与劣势?
  7. 常用SQL查询语句整理笔记【持续更新】
  8. 廖雪峰Python教程梳理
  9. vue学习之监听浏览器宽度
  10. C++生成DLL文件并使用
  11. 转载:全志一些具体工作
  12. android修改HOLO对话框风格
  13. windows 7 桌面图标变白板的问题解决方法
  14. STM32CubeMX安装(全图文安装步骤,一步不落下)
  15. 有限域(2)——理想和商环
  16. 团队协作常见问题分析与解决
  17. 2022年docker面试题大全(持续更新中)
  18. 关于阿里巴巴开发手册不得使用外键与级联,一切外键概念必须在应用层解决的疑惑
  19. WMS系统学习之ModernWMS
  20. Google浏览器主页被搜狗导航劫持解决方法(也适用于火狐浏览器)

热门文章

  1. php aes 3des区别,AES和3DES之间的区别
  2. java createstatement,createStatement参数说明
  3. java net php_Java.netPHP比较 | php外包与php技术服务商
  4. windows配置samba客户端_怎样设置Samba文件服务器以使用Windows客户端
  5. 13 - java包装类
  6. android 跳转动画黑屏,Android8.0 适配解决页面跳转过程出现短暂黑屏的问题
  7. js 二叉树图形_js数据结构和算法(三)二叉树
  8. 多媒体计算机技术的主要特点,多媒体技术主要特点?
  9. 操作失败10秒内未完成启动服务mysql_01-MySQL 命令行-cmd用法-未完成
  10. python 网页自动化框架_python+selenium自动化框架