当前位置: 首页 > article >正文

74 mysql having 的实现

前言

这里 我们主要是 看一下 having 的相关实现 

having 经常是配合 group by 这边进行使用, 进行一个基于 group by 之后的结果的一个, 条件限定

我们这里 以最简单的 group by + having 来进行调试, 他会分为 两个阶段, 一个阶段是 group by 之后的结果输出到临时表, 另外一个阶段是基于这个临时表的一个 条件查询

然后 我们之后再来看一下 它的这边查询的一个 转换

 

 

测试用例

测试数据表如下 

CREATE TABLE `tz_test` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `field1` varchar(128) DEFAULT NULL,
  `field2` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `field_1_2` (`field1`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8

 

测试数据如下 

ba5051582ab6ccc5d41ab1995f8d8e48.png

 

测试 sql 以及执行结果如下 

7a6235f99c8627d900e62e97160268da.png

 

 

group by 的查询

这是 group by 的迭代的处理 

这里是第一条记录, field2 为 1, 目前的 count(*) 为 1, 然后 写入数据到 临时表  

141c5ada81ca65c7a526533879dd72d3.png

 

数据写出到 临时表 “/tmp/#sql_16fb4_0”

43a7b37819ca5aabcaaa35a4dafa0f29.png

 

然后接着 会向该临时文件添加 (2, 1), (3, 1) , (4, 1) , (5, 1) , (6, 1) , (7, 1) , (8, 1) , (9, 1) , (10, 1)

320e7cdce15c5e9ba54cd955eebfff80.png

 

然后最后一条记录, field2 为 1 的记录已经存在, 为 (1, 1), 这里会进行 merge, 将新的 (1, 2) 替换掉原来的 (1, 1)

bafef1a8fa2de34318e3093218439ed1.png

 

 

having 条件的过滤

having 的过滤是在 基于 group by 的临时表进行的过滤 

fe471f64e539b31943fe53e1078a11b3.png

 

然后 后面的比较如下, 右值为 我们输入的常量 2, 左值为我们临时表的 keyField 值为 count(*)

d7123bbf57c18f02463d9c7b25478c23.png

 

然后 外层就是遍历临时表的核心处理

如果不满足 having 的条济, 则跳过, 否则 写出到临时文件 执行下一个阶段的处理

d8faa2a699712851389a79f52eab618a.png

 

 

having 条件查询更新为子查询

假设我们将 上面查询更新为如下子查询, 我们来调试一下 这个过程

select * from (
select field2, count(*) as count from tz_test group by field2
) as tmp 
where tmp.count = 2;

 

这个过程会比 上面的直接 group by + having 会更加复杂一些 

这里是 group by 之后的结果输出到一个临时表 “/tmp/#sql16fb4_1”

85d4a13db978d64a6548befa19d6d0c7.png

 

然后外层是查询 tz_test 做 group by 之后将数据输出到临时表 “/tmp/#sql16fb4_1”

d7975ed91642d6d2d514e16aebfc5b00.png

 

 

然后更外层是我们的 tmp 临时表, 它的数据来源是临时表 “/tmp/#sql16fb4_1”

678c26531ddff5bddb2cb747c1b12ad1.png

 

整体数据传输流程如下 

tz_test 做 group by 之后将结果输出到临时表 “/tmp/#sql16fb4_1” 的流程 

27a13f8f76e79417217e739d2c7a39f5.png

 

临时表 “/tmp/#sql16fb4_1” 传输到 临时表tmp 的过程, 可以看到源表为 临时表 “/tmp/#sql16fb4_1”

fbc5b3eb6187b98db4ceb84f9cc0da7b.png

 

目标表为 临时表tmp 

66a4dd359371e38fb1b70d4c3825122b.png

 

然后查询的时候 field2 上面创建了索引, 直接根据 索引进行查询

然后这里的 索引查询的过程中就已经执行了 “where tmp.count = 2;” 的逻辑处理了 

766c4177ab7d2830dbd2a7af34e43ff5.png

 

 

综上 转换为了子查询之后, 多了一步 数据的从临时表 到 临时表tmp 的传输

但是 临时表tmp 这边的查询 在一定的条件下增加了索引

 

 

完 

 

 

 

 


http://www.kler.cn/a/502426.html

相关文章:

  • 详解 Docker 启动 Windows 容器第二篇:技术原理与未来发展方向
  • python实现自动登录12306抢票 -- selenium
  • C#学习笔记 --- 简单应用
  • B+树的原理及实现
  • 56_多级缓存实现
  • 贪心算法笔记
  • 数据结构与算法之链表: LeetCode 234. 回文链表 (Ts版)
  • sql server 对 nvarchar 类型的列进行 SUM() 运算
  • Spring Boot 动态表操作服务实现
  • OS1.【Linux】大致介绍和环境搭建
  • Redis高危漏洞-GHSA-whxg-wx83-85p5:用户可能会使用特制的 Lua 脚本来触发堆栈缓冲区溢出
  • uc/os-II 原理及应用(八) 系统裁减以及移植到51单片机上
  • 掌握 Ubuntu 终端 mv 与 rename 命令的高效重命名使用方法
  • STM32-笔记42-实时时钟项目
  • uniapp 抖音小程序 getUserProfile:fail must be invoked by user tap gesture
  • CMake学习笔记(1)
  • 开源免费的下载工具AB Download Manager
  • 中等难度——python实现电子宠物和截图工具
  • 概率输出和独热分割掩码的主要区别:
  • 每日学习30分轻松掌握CursorAI:Cursor基础设置与配置
  • 商用服务器密码机的加密技术与优势
  • Win32汇编学习笔记11.游戏辅助的实现
  • fft分析数据求bode图原理
  • 【SQL】进阶知识 -- 删除表的几种方法(包含表内单个字段的删除方法)
  • html5各行各业官网模板源码下载 (4)
  • 初识@ffmpeg/ffmpeg库