【JAVA秒会技术之搞定数据库递归树】Mysql快速实现递归树状查询

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Mysql快速实现递归树状查询 【前言】今天一个好朋友问我的这个问题,以前也没有用到过,恰好有时间,就帮他研究了一下,纯属“现学现卖”,正好在过程中,自己也能学习一下!个人感觉,其实一点也不难,不过是“闻道有先后”,我们是“后”罢了。按照我的习惯,学完东西,总要总结一下嘛,也当做一个备忘录了。   具体需求就不描述了,简而言之,归结为两个: 1.如何通过子节点(cid)加载出所

Mysql快速实现递归树状查询

【前言】今天一个好朋友问我的这个问题,以前也没有用到过,恰好有时间,就帮他研究了一下,纯属“现学现卖”,正好在过程中,自己也能学习一下!个人感觉,其实一点也不难,不过是“闻道有先后”,我们是“后”罢了。按照我的习惯,学完东西,总要总结一下嘛,也当做一个备忘录了。

 

具体需求就不描述了,简而言之,归结为两个:

1.如何通过子节点(cid)加载出所有的父节点(pid)?

2.如何通过父节点(pid)加载出所有的子节点(cid)?

废话不多说,直接上简易教程:

1.创建一个测试表

CREATE TABLE treeNodes
(
 id INT PRIMARY KEY,
     nodename VARCHAR(20),
 pid INT
);

2.编写测试数据

INSERT INTO treeNodes VALUES
(1,'A',0),(2,'B',1),(3,'C',1),
(4,'D',2),(5,'E',2),(6,'F',2),
(7,'G',3),(8,'H',6),(9,'I',0),
(10,'J',8),(11,'K',8),(12,'L',8),
(13,'M',9),(14,'N',12),(15,'O',12),
(16,'P',15),(17,'Q',15);

3.实际树型结构

 

 1:A
  +-- 2:B
  |    +-- 4:D
  |    +-- 5:E
  |    +-- 6:F
  |    |    +-- 8:H
  |    |    |    +-- 10:J
  |    |    |    +-- 11:K 
  |    |    |    +-- 12:L
  |    |    |    |    +-- 14:N
  |    |    |    |    +-- 15:O
  |    |    |    |    |    +-- 16:P
  |    |    |    |    |    +-- 17:Q
  +-- 3:C
  |    +-- 7:G

 9:I
  +-- 13:M


4.创建通过子节点(cid)加载出所有的父节点(pid)的存储函数

DELIMITER //    
CREATE FUNCTION `getParentList`(rootId INT) 
     RETURNS CHAR(255) 
     BEGIN 
		 DECLARE fid INT DEFAULT 1;
		 DECLARE str CHAR(255) DEFAULT rootId;
	     WHILE rootId IS NOT NULL DO 
			SET fid=(SELECT pid FROM treenodes  WHERE rootId=id); 
			 IF fid > 0 THEN  
				 SET str=CONCAT(str,',',fid);   
				 SET rootId=fid;  
			 ELSE 
				SET rootId=fid;  
			 END IF;  
		END WHILE;
		RETURN str;
     END  //

5.测试(找出id=7的所有父节点)  

SELECT getParentList(7); 【结果:7,3,1】

6.创建 通过子节点(cid)加载出所有的父节点(pid)的存储函数  

DELIMITER // 
CREATE FUNCTION `getChildList`(rootId varchar(100)) 
	RETURNS varchar(2000)
	BEGIN 
		DECLARE str varchar(2000);
		DECLARE cid varchar(100); 
		SET str = '$'; 
		SET cid = rootId; 
		WHILE cid is not null DO 
			SET str = concat(str, ',', cid); 
			SELECT group_concat(id) INTO cid FROM treeNodes where FIND_IN_SET(pid, cid) > 0; 
		END WHILE; 
		RETURN str; 
	END //

7.测试(找出id=1的所有子节点)

SELECT getChildList(1); 【结果:$,1,2,3,4,5,6,7,8,10,11,12,14,15,16,17】

8.补充:以上一组简单的教程,主要也是总结于网上的各种资料,其实我个人觉得,对于程序员来说“复制,粘贴”没有什么好不耻的,重点是在于:“复制,粘贴”别人的东西后,要学会分析与进一步的思考,并且能够举一反三,最好之后还能认真的总结一下。这样,别人的东西,才变成了你的东西。并且,你可能比之前那个人做的更好;如此下去,才是一个良性循环!

下面我们就简单分析一下这个存储函数的结构:

 

之后,我又根据朋友的特殊需求,进行了修改,主要是我朋友想查出的并不是各种id,而是希望通过一个子节点的id,直接查出所有父级的名称,便于展示。

DELIMITER // 
CREATE FUNCTION `getParentList`(rootId VARCHAR(100)) 
	RETURNS VARCHAR(1000) 
BEGIN 
	DECLARE parentId VARCHAR(100) DEFAULT ''; 
	DECLARE str VARCHAR(1000) DEFAULT ''; 
	DECLARE parentName VARCHAR(100) DEFAULT ''; 
	SET str = (SELECT budget_account_name FROM pms_budget_account WHERE id = rootId);
	WHILE rootId IS NOT NULL  DO 
		SET parentId =(SELECT parent_id FROM pms_budget_account WHERE id = rootId);
		IF parentId IS NOT NULL THEN 		
			SET parentName = (SELECT budget_account_name FROM pms_budget_account WHERE id = parentId);
			
			SET str = CONCAT(str, ',', parentName); 
			SET rootId = parentId; 
		ELSE 
			SET rootId = parentId; 
		END IF; 
	END WHILE; 
	RETURN str;
END	 //
最后进行测试,达到了朋友想要的预习效果:

 

至此,才是一个完整的学习过程,也是我常用的学习方式:

碰到难题

---> 心态放平,不要怕,暗示自己“一定能解决

---> 各种渠道获取能解决问题的资源(Google/百度,找项目中类似问题参考)

---> 看懂学会别人的东西

---> 深度分析研究实质性原理(一系列连锁知识的快速串烧)

---> 结合自身实际,进行优化变成自己的东西

---> 总结,写出来(使知识更加系统化,回顾加深印象,备忘)

 

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
2月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
354 44
|
2月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
368 1
|
2月前
|
SQL 缓存 监控
MySQL缓存机制:查询缓存与缓冲池优化
MySQL缓存机制是提升数据库性能的关键。本文深入解析了MySQL的缓存体系,包括已弃用的查询缓存和核心的InnoDB缓冲池,帮助理解缓存优化原理。通过合理配置,可显著提升数据库性能,甚至达到10倍以上的效果。
|
3月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
132 4
|
3月前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
806 1
|
2月前
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
2月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
储存过程(Stored Procedures) 和 函数(Functions) : 储存过程和函数允许用户编写 SQL 脚本执行复杂任务.
225 14
|
2月前
|
SQL 关系型数据库 MySQL
MySQL的查询操作语法要点
以上概述了MySQL 中常见且重要 的几种 SQL 查询及其相关概念 这些知识点对任何希望有效利用 MySQL 进行数据库管理工作者都至关重要
108 15
|
2月前
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
2月前
|
SQL 关系型数据库 MySQL
MySQL入门指南:从安装到第一个查询
本文为MySQL数据库入门指南,内容涵盖从安装配置到基础操作与SQL语法的详细教程。文章首先介绍在Windows、macOS和Linux系统中安装MySQL的步骤,并指导进行初始配置和安全设置。随后讲解数据库和表的创建与管理,包括表结构设计、字段定义和约束设置。接着系统介绍SQL语句的基本操作,如插入、查询、更新和删除数据。此外,文章还涉及高级查询技巧,包括多表连接、聚合函数和子查询的应用。通过实战案例,帮助读者掌握复杂查询与数据修改。最后附有常见问题解答和实用技巧,如数据导入导出和常用函数使用。适合初学者快速入门MySQL数据库,助力数据库技能提升。

推荐镜像

更多