探索 MySQL 递归查询,优雅的给树结构分页!

一、概述

递归查询是一种在数据库中处理具有层级结构数据的技术。它通过在查询语句中嵌套引用自身,以实现对嵌套数据的查询。递归查询在处理树状结构、父子关系或层级关系的数据时非常有用。

MySQL中,递归查询可以使用WITH RECURSIVE语句来实现。该语句允许我们定义一个递归查询,并在查询中引用自身。

递归查询通常包含两个部分:基础查询递归查询

图片

  • 基础查询是指查询的起始点,它返回递归查询中的初始结果集。

  • 递归查询部分定义了如何从基础查询的结果集中继续查询下一层的数据,直到满足终止条件为止。

注意:MySQL是在8.0才引入的窗口函数功能;属于MySQL8的新特性

二、结构

递归查询通常包含以下几个关键元素:

图片

  • 初始查询Anchor Query):这是递归查询的起点,返回初始结果集。它是递归查询的第一步。

  • 递归查询Recursive Query):这是递归查询的核心部分,它引用自身并定义了如何从上一层的结果集中继续查询下一层的数据。递归查询通常包含一个递归关系,通过引用父节点与子节点之间的关联来构建数据的层级结构。

  • 终止条件Termination Condition):这是递归查询的结束条件,用于指定何时停止递归查询。终止条件通常是基于已查询的数据的某种条件或限制。

三、递归查询的执行过程

递归查询的执行过程如下:

图片

  1. 执行初始查询,获取初始结果集。

  2. 将初始结果集作为递归查询的输入,执行递归查询,并将结果集与初始结果集合并。

  3. 重复执行递归查询,直到满足终止条件为止。

四、递归查询的应用场景

递归查询在许多应用场景中都是非常有用的。以下是一些常见的递归查询的应用场景:

图片

注意:以上内容只是递归查询的一些常见应用场景,实际上,递归查询可以适用于任何具有层级或递归结构的数据。通过合理地设计和应用递归查询,可以更轻松地处理复杂的数据关系和层次结构,提供更高效和灵活的数据访问和分析能力。

五、一个案例演示递归查询

为了更好的认识递归查询,这里使用一个简单的组织架构来演示一下递归查询是怎么实现的。

5.1 创建一个组织架构表

CREATE TABLE `organization` (
  `org_id` int NOT NULL COMMENT '主键',
  `org_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '组织名称',
  `parent_id` int DEFAULT NULL COMMENT '父组织id',
  `org_level` int DEFAULT NULL COMMENT '组织级别',
  PRIMARY KEY (`org_id`),
  KEY `parent_id` (`parent_id`),
  CONSTRAINT `organization_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `organization` (`org_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='公司组织架构';

5.2 在这个组织架构表里面插入一些数据

INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (1, '集团总部', NULL, 1);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (2, '华北分公司', 1, 2);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (3, '华南分公司', 1, 2);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (4, '华北-北京公司', 2, 3);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (5, '华北-内蒙公司', 2, 3);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (6, '华南-广州公司', 3, 3);
INSERT INTO `organization`(`org_id`, `org_name`, `parent_id`, `org_level`) VALUES (7, '华南-深圳公司', 3, 3);

5.3 使用递归查询分页查看我们的组织架构

WITH RECURSIVE RecursiveOrganization AS (
  SELECT org_id, org_name, parent_id, org_level
  FROM organization
  WHERE parent_id IS NULL  -- 查找根节点
  UNION ALL
  SELECT o.org_id, o.org_name, o.parent_id, o.org_level
  FROM organization o
  INNER JOIN RecursiveOrganization ro ON ro.org_id = o.parent_id
)
SELECT org_id, org_name, parent_id, org_level
FROM RecursiveOrganization
ORDER BY org_id
LIMIT 2 OFFSET 0;  -- 设置每页的条目数量和偏移量

解析一下这个SQL

  • 首先,使用WITH RECURSIVE子句创建了一个名为RecursiveOrganization的递归查询视图。在初始查询部分,通过WHERE parent_id IS NULL条件查找根节点,选择了根节点的组织信息(org_id, org_name, parent_id, org_level)

  • 然后,使用UNION ALLINNER JOIN将递归查询与organization表连接起来,逐级递归获取下级组织的信息。通过SELECT o.org_id, o.org_name, o.parent_id, o.org_level选择下级组织的信息,并使用ON ro.org_id = o.parent_id指定连接条件。

  • 最后,从RecursiveOrganization视图中选择所需的组织架构数据,并使用ORDER BY对结果按org_id进行排序。通过LIMITOFFSET可以设置每页的条目数量和偏移量,实现分页查询。

六、总结

递归查询在处理父子结构、树状结构或层级关系的数据时非常有用。它允许我们轻松地查询所有层级的数据,无论层级有多深。递归查询还可以用于处理分页查询、路径查询、层级计算等各种复杂的查询需求。

需要注意的是,递归查询可能会占用较多的系统资源,并且在处理大型数据集时可能会导致性能问题。因此,在使用递归查询时,需要谨慎设计和优化查询,以确保查询的效率和性能。

最后说一句(求关注!别白嫖!)

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。

关注公众号:woniuxgg,在公众号中回复:笔记  就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

利用HubSpot出海CRM和人工智能技术提升出海业务的效率和效果

在当今数字化时代,智能化营销已经成为企业获取客户和扩大市场份额的关键策略。特别是对于出海业务而言,利用智能化营销技术来应对不同文化、语言和市场的挑战,已经成为企业竞争的关键优势。今天运营坛将带领大家探讨如何利用HubSpot CRM和人工…

隐式提交的引申之DB/SAP LUW

1、写在前面 之前发表过《聊聊更新表时的隐式提交》一文,向大家介绍隐式提交,对于数据库操作的作用。 有粉丝看过后,提出了自己的疑问: 首先解释一下,该粉丝大致的问题和代码含义为: 在创建销售订单增强…

力扣-160. 相交链表(双指针)

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意,函数返回结果后&a…

一道有深度的面试题:本地悲观锁实现计数器需要加 volatile 吗?

故事背景 团队内部前几天讨论了一个面试题,在本地用乐观锁和悲观锁实现计数器需要volatile关键字吗?毫无疑问,使用乐观锁一定是需要的。但使用悲观锁需要呢? 张三:不需要吧,每次不都是一个线程访问变量吗&a…

什么是字节码?采用字节码的好处是什么?

在 Java 中,JVM 可以理解的代码就叫做字节码(即扩展名为 .class 的文件),字节码是一种中间代码,它是由源代码经过编译生成的一种二进制表示形式。字节码通常不针对特定的硬件平台,而是针对虚拟机设计的&…

antd vue Tabs控件的使用

Ant Design Vue-------Tabs标签页 今天就讲讲Ant Design Vue下的控件----tabs 标签页 结合项目中的需求,讲一下该控件如何使用,需求: (1)竖排样式 (2)如何使用v-for绑定数据源 (3…

蓝桥杯专题 bfs习题详解

1.离开中山路 #include<iostream> #include<cstring> #include<queue> #include<algorithm> #include<string> using namespace std; int x1,x2,y1,y2; int n,n1,m1; const int N1010;typedef pair<int,int> PII; queue<PII> q;int …

CTP-API开发系列之九:行情登录及订阅代码

CTP-API开发系列之九&#xff1a;行情登录及订阅代码 前情回顾全局配置参数行情初始化代码行情登录行情订阅行情接收注意事项 前情回顾 CTP-API开发系列之一&#xff1a;各版本更新说明&#xff08;持续更新&#xff09; CTP-API开发系列之二&#xff1a;问题汇总&#xff08;…

(done) NLP “bag-of-words“ 方法 (带有二元分类和多元分类两个例子)词袋模型、BoW

一个视频&#xff1a;https://www.bilibili.com/video/BV1mb4y1y7EB/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c7355c5490fc600 这里有个视频&#xff0c;讲解得更加生动形象一些 总得来说&#xff0c;词袋模型(Bow, bag-of-words) 是最简…

fs模块 文件写入 之 流式写入

一、流式写入&#xff08;createWriteStream &#xff09;与 文件的同步异步写入&#xff08;writeFile &#xff09;的区别&#xff1a; 1》程序打开一个文件是需要耗费资源的&#xff0c;流式写入可以减少打开关闭文件的次数。 2》文件的流式写入方式适用于大文件写入或者频…

ChatGPT国内能用吗?中国用户怎么才能使用ChatGPT?

与ChatGPT类似的国内网站&#xff0c;他们都能提供和ChatGPT相似的能力&#xff0c;而且可以在国内直接使用。 点击直达方式 百科GPT官网&#xff1a;baikegpt.cn ChatGPT是基于GPT-3.5架构的语言模型的一个实例&#xff0c;由OpenAI开发。以下是ChatGPT的发展历史&#xff1…

《ElementPlus 与 ElementUI 差异集合》el-button 属性 type=“text“ 被删除

差异 element-ui el-button中&#xff0c;属性 type"text" 定义文字按钮&#xff0c;也是链接按钮&#xff1b;element-plus el-button中&#xff0c;改为新增属性 link 并与其它 type 值配合使用&#xff1b; // element-ui <el-button type"text"&g…

(Linux学习九)管道、重定向介绍

FD:文件描述符。 0,1,2,3&#xff0c;&#xff0c;&#xff0c;。进程打开文件所用。 0标准输入 1 标准输出 2 标准错误输出 3普通文件 一、管道 | 命令 | tee | xargs | 命令1的输出&#xff0c;作为命令2的输入&#xff0c;命令2的输出作为命令3的输入 | tee 三通&#xff…

Qt+FFmpeg+opengl从零制作视频播放器-3.解封装

解封装:如下图所示,就是将FLV、MKV、MP4等文件解封装为视频H.264或H.265压缩数据,音频MP3或AAC的压缩数据,下图为常用的基本操作。 ffmpeg使用解封装的基本流程如下: 在使用FFmpeg API之前,需要先注册API,然后才能使用API。当然,新版本ffmpeg库不需要再调用下面的方法…

原型模式(Clone)——创建型模式

原型模式(clone)——创建型模式 什么是原型模式&#xff1f; 原型模式是一种创建型设计模式&#xff0c; 使你能够复制已有对象&#xff0c; 而又无需依赖它们所属的类。 总结&#xff1a;需要在继承体系下&#xff0c;实现一个clone接口&#xff0c;在这个方法中以本身作为拷…

技术方案|某工业集团PaaS容灾方案

在当今快速发展的数字化时代&#xff0c;业务的连续性和稳定性已成为企业核心竞争力的重要组成部分。然而&#xff0c;由于各种原因&#xff0c;企业常常面临着数据丢失、系统瘫痪等潜在风险。因此&#xff0c;制定一套科学、高效的容灾方案至关重要。本文将围绕某全球领先的工…

WRF模型运行教程(ububtu系统)--III.运行WRF模型(官网案例)

创建DATA目录 1、创建一个DATA目录用于存放数据&#xff08;一般为fnl数据&#xff0c;放在Build_WRF目录下&#xff09;。 mkdir DATA 2、将数据放在DATA文件夹里。 3、链接数据 cd ~/Build_WRF/WPS/ ./link_grib.csh ~/Build_WRF/DATA/data/fnl ln -sf ungrib/Variab…

数据结构02:线性表 顺序表习题01[C++]

图源&#xff1a;文心一言 考研笔记整理~&#x1f95d;&#x1f95d; 之前的博文链接在此&#xff1a;数据结构02&#xff1a;线性表[顺序表链表]_线性链表-CSDN博客~&#x1f95d;&#x1f95d; 本篇作为线性表的代码补充&#xff0c;供小伙伴们参考~&#x1f95d;&#x1…

(C语言)strcat函数详解与模拟实现与strncat函数详解

目录 1. strcat函数详解 1. strcat函数模拟实现 3. strcat函数的危险性 4. strncat函数详解 4.1 strncat函数的特殊情况验证 1. strcat函数详解 头文件<string.h> 该函数是用来对字符串末尾追加字符串的&#xff0c;有两个参数&#xff0c;destination是要被追加的字…

LVS 负载均衡-DR模式

一 . DR 模式 直接路由 &#xff1a; 1.介绍&#xff1a; 直接路由&#xff08;Direct Routing&#xff09;&#xff1a;简称 DR 模式&#xff0c;采用半开放式的网络结构&#xff0c;与 TUN 模式的结构类似&#xff0c;但各节点并不是分散在各地&#xff0c;而是与调度器位…