mysql group by null_MySQL无GROUP BY直接HAVING返回空的问题分析

有一张表,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 |

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

2 rows in set (0.00 sec)

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

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

| a    | id |

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

|    1 |  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 |

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

2 rows in set (0.00 sec)

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

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

| a    | id |

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

|   10 |  1 |

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

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 |

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

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 |

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

2 rows in set (0.00 sec)

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

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

| a    | id |

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

|   10 |  1 |

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

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 |

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

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 |

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

2 rows in set (0.00 sec)

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/566659.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c mysql 免安装版_MySQL5.6免安装版环境配置图文教程

MySQL是一个小巧玲珑但功能强大的数据库,目前十分流行。但是官网给出的安装包有两种格式,一个是msi格式,一个是zip格式的。很多人下了zip格式的解压发现没有setup.exe,面对一堆文件一头雾水,不知如何安装。下面小编将介…

python士兵突击_想自学Python进入该行业成为一名自己一直以来就很羡慕和钦佩的程序员,过来人的你有什么想分享的吗?...

多说无益就是干,学习编程也这样。我们下面主要通过以下三个步骤给出建议:1.确定目标(成为一个能干活的Python需要掌握哪些技能)。我们可以通过市面上对于Python工程师对招聘要求,去分析,具体需要掌握哪些内容。这个详细内容可以在…

启动项 mysql命令大全_mysql常用命令

一、登录mysql数据库1、连接本地mysql数据库,默认端口为3306#mysql –u root –p 123456 //-u:指定用户 -p:指定与用户对应的密码2、通过IP和端口连接远程mysql服务器#mysql –u root –p 123456 –h 192.168.100.1 –P 3306二、数据库操作语句1、显示所…

MDL锁导致mysql夯住_MySQL MetaData Lock 案例分享

前言:今天开发童鞋遇到一个奇怪的问题,在测试环境里面执行drop database dbname发现一直夯住不动,等了很久也没有执行,于是问题就到我这里了一、什么是MetaData Lock?MetaData Lock即元数据锁,在数据库中元…

ubuntu16 黑主题_给Ubuntu 8.10安装超炫酷黑色新主题

Linux系统的Netbook定做了一套漂亮的界面,名称叫做 HP Mini 1000 Mi Edition。这套界面是基于 Ubuntu 8.04 Hardy Heron的,平常我们熟悉的Ubuntu程序等都可以在这里都使用.不过让 Mi Edition 脱颖而出的是这看起来根本不像是我们平时看过的Ubuntu界面, 看上去倒像媒体中心。这个…

docker 分布式管理群集_Coolpy7分布式物联网MQTT集群搭建

Coolpy7分布式技术,支持多个Coolpy7 Core提供跨数据中心(多活)模式组建群集,支持群集零手动维护(基于Gossip分布式协议作为群集节点状态维护)。Coolpy7从版本号V7.3.2.3开始支持本功能。请到Coolpy7之github项目release下载相关版本https://github.com/C…

vue 数值 拼接字符串_【Vue原理】Compile - 白话版

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧 研究基于 Vue版本 【2.5.17】如果你觉得排版难看,请点击 下面链…

gpio驱动蜂鸣器出现破音_五款蜂鸣器驱动电路原理图

蜂鸣器驱动电路图一:典型的蜂鸣器驱动电路,蜂鸣器驱动电路一般包含:一个三极管、一个蜂鸣器、一个续流二极管、一个滤波电容。1、蜂鸣器:发声元件,在其两端施加直流电压(有源蜂鸣器)或者方波(无源蜂鸣器)就可以发声&am…

php和mysql的实践报告_PHP+MySQL项目开发与实践

前言部分基础篇任务一PHP基础知识简介1.1静态网页与动态网页的工作原理1.1.1静态网页与工作原理1.1.2动态网页与工作原理1.2初识PHP1.3习题任务二PHP程序的运行环境搭建2.1配置Apache服务器2.1.1安装Apache服务器2.1.2Apache服务器安装过程中的问题及解决方案2.1.3Apache主目录…

mediumint 在mysql 中是什么类型_mysql中bigint、int、mediumint、smallint 和 tinyint的取值范围...

mysql数据库设计,其中,对于数据性能优化,字段类型考虑很重要,搜集了些资料,整理分享出来,这篇为有关mysql整型bigint、int、mediumint、smallint 和 tinyint的语法介绍,如下:1、bigi…

mysql备份还原数据库操作系统_mysql 命令行备份还原数据库操作

一 备份操作1.备份全部数据库mysqldump -uroot -p --all databases > aa.sql2.备份某个数据库并压缩mysqldump -uroot -p databasename |gzip > aa.sql.gz3 .备份单个表mysqldump -uroot -p -table dbname tbname1 tbname2 >aa.sql4.同时备份多个数据库mysqldump -ur…

python表示当前对象_对象操作

[TOC]# 对象操作## help:返回对象的帮助信息~~~>>> help(str)Help on class str in module builtins:class str(object)| str(object) -> str| str(bytes_or_buffer[, encoding[, errors]]) -> str|| Create a new string object from the given object. If enc…

中国大学慕课python答案第七章_中国大学慕课mooc用Python玩转数据章节答案

嵌体来源A.嵌入牙冠内的修复体 B.没有覆盖前牙唇面或后牙颊面的部分冠修复体艺术不是象牙塔里的_____ ,所谓的“为艺术而艺术”,说到底不过是唯美主义_____的志向。自古以来,艺小轿车的速度比卡车的速度每小时快6千米,小轿车和卡车…

mysql 多项式_mysql主从复制原理及实现

一.主从复制原理利用MySQL提供的Replication,其实就是Slave从Master获取Binary log文件,然后再本地镜像的执行日志中记录的操作。由于主从复制的过程是异步的,因此Slave和Master之间的数据有可能存在延迟的现象,此时只能保证数据最…

python迭代器是什么百度百科,python迭代器的接口是什么?

What are the required methods for defining an iterator? For instance, on the following Infinity iterator, are its methods sufficient? Are there other standard or de factor standard methods that define an iterator?class Infinity(object):def __init__(self…

python逻辑表达式3+45and_python入门到精通(一)| python基础语法与各种运算符的使用...

一、python中的基础语法1、输入语句 input格式:变量input(“输入提示信息”)功能:从键盘上输入一行文本信息到变量中,可以强转为各种数据类型。案例: xinput(“您的个人基本信息”)注意点:只能接受一行信息2 input语句…

java中文分词算法_Java实现逆向最大匹配中文分词算法

写道//Java实现逆向最大匹配中文分词算法public class SplitChineseCharacter {public static void main(String[] args) {String input "太好了,今天是星期六啊"; // 要匹配的字符串new Split(input).start();}}class Split {private String[] dictiona…

途牛java面试题_途牛java面试题.docx

途牛java面试题途牛java面试题  QUESTION NO: 1   publicclass Test1 {   publicstaticvoid changeStr(String str){   str"welcome";   }   publicstaticvoid main(String args) {   String str"1234";   changeStr(str);   (str);   …

java httpclient 异步请求_java_java实现HttpClient异步请求资源的方法,本文实例讲述了java实现HttpClien - phpStudy...

java实现HttpClient异步请求资源的方法本文实例讲述了java实现HttpClient异步请求资源的方法。分享给大家供大家参考。具体实现方法如下:package demo;import java.util.concurrent.CountDownLatch;import org.apache.http.HttpResponse;import org.apache.http.cli…

idea创建web项目运行报404错误_使用IDEA新建Web工程启动报404的错误

新换了一个项目组被人吐槽配置文件都能写错,所以打算从头开始一步步搭建一个项目,包含ssm基础框架、mongodb工具类、redis工具类、jsf配置、log配置等今天先来搭建一个web工程。工程搭建好运行时发现404我们都知道,一般404都是由于请求资源的…