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

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 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/百度,找项目中类似问题参考)

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

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

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

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

 

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
17天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
46 11
|
27天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
62 7
|
9天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
8天前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过使用 MongoDB Connector for BI 和 JDBC,开发者可以在 Java 中使用 SQL 语法查询 MongoDB 数据库。这种方法对于熟悉 SQL 的团队非常有帮助,能够快速实现对 MongoDB 数据的操作。同时,也需要注意到这种方法的性能和功能限制,根据具体应用场景进行选择和优化。
33 9
|
23天前
|
NoSQL Java 关系型数据库
Liunx部署java项目Tomcat、Redis、Mysql教程
本文详细介绍了如何在 Linux 服务器上安装和配置 Tomcat、MySQL 和 Redis,并部署 Java 项目。通过这些步骤,您可以搭建一个高效稳定的 Java 应用运行环境。希望本文能为您在实际操作中提供有价值的参考。
111 26
|
29天前
|
存储 缓存 网络协议
数据库执行查询请求的过程?
客户端发起TCP连接请求,服务端通过连接器验证主机信息、用户名及密码,验证通过后创建专用进程处理交互。服务端进程缓存以减少创建和销毁线程的开销。后续步骤包括缓存查询(8.0版后移除)、语法解析、查询优化及存储引擎调用,最终返回查询结果。
29 6
|
27天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
2月前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
39 8
|
2月前
|
关系型数据库 MySQL Java
MySQL索引优化与Java应用实践
【11月更文挑战第25天】在大数据量和高并发的业务场景下,MySQL数据库的索引优化是提升查询性能的关键。本文将深入探讨MySQL索引的多种类型、优化策略及其在Java应用中的实践,通过历史背景、业务场景、底层原理的介绍,并结合Java示例代码,帮助Java架构师更好地理解并应用这些技术。
53 2
|
2月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。