当前位置:首页 > 数码 > MySQL中经常使用递归查问轻松找到一切子节点 (mysql中DISTINCT的用法)

MySQL中经常使用递归查问轻松找到一切子节点 (mysql中DISTINCT的用法)

admin7个月前 (05-04)数码21

背景

名目中遇到一个需求,要求查出菜单节点的一切节点,在网上查了一下,大少数的方法用到了存储环节,由于线上环境不能随意参与存储环节。

因此在这里驳回相似递归的方法对组织下的一切子节点启动查问。

预备

创立组织表:

CREATETABLEgroups(`group_id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'组织ID',`parent_id`int(11)DEFAULTNULLCOMMENT'父节点ID',`group_name`varchar(128)DEFAULTNULLCOMMENT'组织称号',PRIMARYKEY(`group_id`))ENGINE=InnoDBAUTO_INCREMENT=0DEFAULTCHARSET=utf8;

写入数据:

INSERTINTOgroupsVALUES(0,null,'系统治理组织');INSERTINTOgroupsVALUES(1,0,'中国电信股份有限公司');INSERTINTOgroupsVALUES(2,1,'万州分公司');INSERTINTOgroupsVALUES(3,1,'涪陵分公司');INSERTINTOgroupsVALUES(4,2,'龙都支局');INSERTINTOgroupsVALUES(5,2,'新田支局');INSERTINTOgroupsVALUES(6,3,'马武支局');INSERTINTOgroupsVALUES(7,3,'南沱支局');INSERTINTOgroupsVALUES(8,4,'党群上班部');INSERTINTOgroupsVALUES(9,5,'客户服务部');INSERTINTOgroupsVALUES(10,6,'洽购和供应链治理事业部');INSERTINTOgroupsVALUES(11,7,'网络和消息安保治理部');

树状结构:

-系统治理组织-中国电信股份有限公司-万州分公司-龙都支局-党群上班部-新田支局-客户服务部-涪陵分公司-马武支局-洽购和供应链治理事业部-南沱支局-网络和消息安保治理部

成功

查问

selectgroup_id,group_namefrom(selectt1.group_id,t1.parent_id,t1.group_name,t2.pids,if(find_in_set(parent_id,@pids)>0,@pids:=concat(@pids,',',group_id),0)asischildfrom(selectgroup_id,parent_id,group_namefrom`groups`)t1,(select@pids:=#{groupId}aspids)t2)t3whereischild!=0;

比如,要查问的万州分公司下一切子节点,只需将 #{groupId} 变卦为万州分公司的组织ID即可:

group_id|group_name|--------+----------+4|龙都支局|5|新田支局|8|党群上班部|9|客户服务部|

语句解析

group_id|parent_id|group_name|--------+---------+-----------+0||系统治理组织|1|0|中国电信股份有限公司|2|1|万州分公司|3|1|涪陵分公司|4|2|龙都支局|5|2|新田支局|6|3|马武支局|7|3|南沱支局|8|4|党群上班部|9|5|客户服务部|10|6|洽购和供应链治理事业部|11|7|网络和消息安保治理部|
pids|----+2|
group_id|parent_id|group_name|pids|ischild|--------+---------+-----------+----+---------+0||系统治理组织|2|0|1|0|中国电信股份有限公司|2|0|2|1|万州分公司|2|0|3|1|涪陵分公司|2|0|4|2|龙都支局|2|2,4|5|2|新田支局|2|2,4,5|6|3|马武支局|2|0|7|3|南沱支局|2|0|8|4|党群上班部|2|2,4,5,8|9|5|客户服务部|2|2,4,5,8,9|10|6|洽购和供应链治理事业部|2|0|11|7|网络和消息安保治理部|2|0|
group_id|group_name|--------+----------+4|龙都支局|5|新田支局|8|党群上班部|9|客户服务部|

8.0版本

MySQL中经常使用递归查问轻松找到一切子节点
WITHRECURSIVEsubordinatesAS(SELECTgroup_id,group_name,parent_idFROMgroupsWHEREparent_id=2--指定父节点IDUNIONALLSELECTg.group_id,g.group_name,g.parent_idFROMgroupsgINNERJOINsubordinatessONs.group_id=g.parent_id)SELECT*FROMsubordinates;
group_id|group_name|parent_id|--------+----------+---------+4|龙都支局|2|5|新田支局|2|8|党群上班部|4|9|客户服务部|5|

代码递归

@Testpublicvoidtest1(){List<Map<String,Object>>groupList=newArrayList<>();groupList=queryListParentId(2,groupList);System.out.println(groupList);groupList.clear();System.out.println("=====================");List<String>list=newArrayList<>();list.add("3");groupList=queryListParentId2(list,groupList);System.out.println(groupList);}//模式一,循环遍历查问publicList<Map<String,Object>>queryListParentId(IntegerparentId,List<Map<String,Object>>groupList){Stringsql="selectgroup_id,group_namefromgroupswhereparent_id="+parentId;List<Map<String,Object>>list=jdbcTemplate.queryForList(sql);if(!CollectionUtils.isEmpty(list)){groupList.addAll(list);for(Map<String,Object>map:list){queryListParentId((Integer)map.get("group_id"),groupList);}}returngroupList;}//模式二,经常使用find_in_set函数publicList<Map<String,Object>>queryListParentId2(List<String>parentId,List<Map<String,Object>>groupList){Stringjoin=String.join(",",parentId);Stringsql="selectgroup_id,group_namefromgroupswherefind_in_set(parent_id,'"+join+"')";List<Map<String,Object>>list=jdbcTemplate.queryForList(sql);if(!CollectionUtils.isEmpty(list)){groupList.addAll(list);List<String>collect=list.stream().map(map->map.get("group_id")+"").collect(Collectors.toList());queryListParentId2(collect,groupList);}returngroupList;}
[{group_id=4,group_name=龙都支局},{group_id=5,group_name=新田支局},{group_id=8,group_name=党群上班部},{group_id=9,group_name=客户服务部}]=====================[{group_id=6,group_name=马武支局},{group_id=7,group_name=南沱支局},{group_id=10,group_name=洽购和供应链治理事业部},{group_id=11,group_name=网络和消息安保治理部}]

在 SQL 中,你可以使用递归查询来实现递归函数。 递归查询是一种查询,其中结果集由一条或多条 SELECT 语句和一条用于查找下一级行的 UNION ALL 语句组成。 例如,假设你有一张表,其中包含父子关系的信息(即,每个记录都有一个父级 ID,表示它的父级),你可以使用以下递归查询来查询每个记录的所有祖先:WITH RECURSIVE ancestors AS (-- 初始查询SELECT id, parent_idFROM your_tableWHERE id = :your_idUNION ALL-- 递归查询SELECT , _idFROM your_table tINNER JOIN ancestors a ON = _id)SELECT id FROM ancestors;在这个查询中,我们使用了一个递归关系,其中第一个 SELECT 语句是初始查询,用于查询给定 ID 的记录。 第二个 SELECT 语句是递归查询,用于查询与当前记录的父级相关的记录。 通过将这两个 SELECT 语句用 UNION ALL 连接起来,我们就可以获得所有祖先的列表了。

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: MySQL

“MySQL中经常使用递归查问轻松找到一切子节点 (mysql中DISTINCT的用法)” 的相关文章

实用性极强的-MySQL-查询优化策略 (实用性极强的app)

实用性极强的-MySQL-查询优化策略 (实用性极强的app)

在程序上线运行一段时间后,一旦数据量上去了,或多或少会感觉到系统出现延迟、卡顿等现象,出现这种问题,就需要程序员或架构师进行系统调优工作了。其中,大量的实践经验表明,调优的手段尽管有很多,但涉及到...

Java开发者的MySQL数据库版本管理策略-从规划到部署的全面指南 (java开发工程师)

Java开发者的MySQL数据库版本管理策略-从规划到部署的全面指南 (java开发工程师)

数据库是软件开发中常用的关系型数据库之一。版本管理是保障数据库稳定性和可靠性的重要方面。本文将介绍针对 Java 开发者的 MySQL 数据库版本管理策略,包括版本控制工具选择、数据库脚本管理、变...

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

MySQL-一探究竟-核心模块揭秘 (mysql-bin文件可以删除吗)

Undo Segment Caching To improve the efficiency of undo segmentallocation, InnoDB caches some un...

优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

优化数据统计的终极指南-MySQL-提升查询性能的秘诀 (优化数据统计工具)

在业务场景中,我们经常需要统计当前已有的业务数据,例如商品库内商品的数量、每天的用户订单数量等。此时,我们需要使用统计功能来实现。 count()实现方式 对于不同的数据库引擎,co...

实战-MySQL-数据库压力测试与性能评估方法-Java (实战篮球鞋排名)

实战-MySQL-数据库压力测试与性能评估方法-Java (实战篮球鞋排名)

压力测试的目的和重要性 压力测试是模拟真实环境中并发用户访问数据库的场景,通过增加负载来测试数据库系统的性能表现。压力测试的目的是发现数据库在高负载下的性能瓶颈、资源利用情况和响应时间等指...

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制原理简介-MySQL (主从复制原理mysql)

主从复制(Master-SlaveReplication)是一种数据复制技术,用于在多个数据库主机之间的数据同步。在主从复制架构中,一个主机被设置为主主机(Master),充任数据源,其余主机被设...

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

全面指南-如何解决-MySQL-主从延时问题 (全面指导)

一、什么是主从延时? 主从延时,是指从数据库从主数据库复制数据时产生的时间差。它会导致从库中的数据与主库不一致。 二、为什么会主从延时? 1. 主从复制原理 MySQL的...

如何在MySQL中成功数据的版本治理和回滚操作 (如何在mysql数据库中添加数据)

如何在MySQL中成功数据的版本治理和回滚操作 (如何在mysql数据库中添加数据)

成功数据的版本治理和回滚操作在中可以经过以下几种模式成功,包含经常使用事务、备份恢复、日志和版本控制工具等。上方将详细引见这些方法。 1.经常使用事务: MySQL允许事务操作,可以经...