mysql查询树形结构子节点_MySQL递归查询所有子节点,树形结构查询

--表结构

CREATE TABLE `address` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`code_value` varchar(32) DEFAULT NULL COMMENT '区域编码',

`name` varchar(128) DEFAULT NULL COMMENT '区域名称',

`remark` varchar(128) DEFAULT NULL COMMENT '说明',

`pid` varchar(32) DEFAULT NULL COMMENT 'pid是code_value',

PRIMARY KEY (`id`),

KEY `ix_name` (`name`,`code_value`,`pid`)

) ENGINE=InnoDB AUTO_INCREMENT=1033 DEFAULT CHARSET=utf8 COMMENT='行政区域表';

--mysql 实现树结构查询

--方法一

CREATE PROCEDURE sp_showChildLst(IN rootId varchar(20))

BEGIN

CREATE TEMPORARY TABLE IF NOT EXISTS tmpLst

(sno int primary key auto_increment,code_value VARCHAR(20),depth int);

DELETE FROM tmpLst;

CALL sp_createChildLst(rootId,0);

select tmpLst.*,address.* from tmpLst,address where tmpLst.code_value=address.code_value order by tmpLst.sno;

END

CREATE PROCEDURE sp_createChildLst(IN rootId varchar(20),IN nDepth INT)

BEGIN

DECLARE done INT DEFAULT 0;

DECLARE b VARCHAR(20);

DECLARE cur1 CURSOR FOR SELECT code_value FROM address where pid=rootId;

DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

insert into tmpLst values (null,rootId,nDepth);

SET @@max_sp_recursion_depth = 10;

OPEN cur1;

FETCH cur1 INTO b;

WHILE done=0 DO

CALL sp_createChildLst(b,nDepth+1);

FETCH cur1 INTO b;

END WHILE;

CLOSE cur1;

END

--方法二(此方法有线程安全问题)

CREATE PROCEDURE sp_getAddressChild_list(in idd varchar(36))

begin

declare lev int;

set lev=1;

drop table if exists tmp1;

CREATE TABLE tmp1(code_value VARCHAR(36),`name` varchar(50),pid varchar(36) ,levv INT);

INSERT tmp1 SELECT code_value,`name`,pid,1 FROM address WHERE pid=idd;

while row_count()>0

do

set lev=lev+1;

INSERT tmp1 SELECT t.code_value,t.`name`,t.pid,lev from address t join tmp1 a on t.pid=a.code_value AND levv=lev-1;

end while ;

INSERT tmp1 SELECT code_value,`name`,pid,0 FROM address WHERE code_value=idd;

SELECT * FROM tmp1;

end

--方法三

CREATE FUNCTION fn_getAddress_ChildList_test(rootId INT) RETURNS varchar(1000) CHARSET utf8 #rootId为你要查询的节点

BEGIN

#声明两个临时变量

DECLARE temp VARCHAR(1000);

DECLARE tempChd VARCHAR(1000);

SET temp = '$';

SET tempChd=CAST(rootId AS CHAR);#把rootId强制转换为字符

WHILE tempChd is not null DO

SET temp = CONCAT(temp,',',tempChd);#循环把所有节点连接成字符串。

SELECT GROUP_CONCAT(code_value) INTO tempChd FROM address where FIND_IN_SET(pid,tempChd)>0;

END WHILE;

RETURN temp;

END

--方法四

CREATE PROCEDURE sp_findAddressChild(iid varchar(50),layer bigint(20))

BEGIN

/*创建接受查询的临时表 */

create temporary table if not exists tmp_table(id varchar(50),code_value varchar(50),name varchar(50),pid VARCHAR(50)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*最高允许递归数*/

SET @@max_sp_recursion_depth = 10 ;

call sp_iterativeAddress(iid,layer);/*核心数据收集*/

select * from tmp_table ;/* 展现 */

drop temporary table if exists tmp_table ;/*删除临时表*/

END

CREATE PROCEDURE sp_iterativeAddress(iid varchar(50),layer bigint(20))

BEGIN

DECLARE t_id INT;

declare t_codeValue varchar(50) default iid ;

declare t_name varchar(50) character set utf8;

declare t_pid varchar(50) character set utf8;

/* 游标定义 */

declare cur1 CURSOR FOR select id,code_value,`name`,pid from address where pid=iid ;

declare CONTINUE HANDLER FOR SQLSTATE '02000' SET t_codeValue = null;

/* 允许递归深度 */

if layer>0 then

OPEN cur1 ;

FETCH cur1 INTO t_id,t_codeValue,t_name,t_pid ;

WHILE ( t_codeValue is not null )

DO

/* 核心数据收集 */

insert into tmp_table values(t_id,t_codeValue,t_name,t_pid);

call sp_iterativeAddress(t_codeValue,layer-1);

FETCH cur1 INTO t_id,t_codeValue,t_name,t_pid ;

END WHILE;

end if;

END

--方法五 SQL实现

SELECT `name`,code_value AS code_value,pid AS 父ID ,levels AS 父到子之间级数, paths AS 父到子路径 FROM (

SELECT `name`,code_value,pid,

@le:= IF (pid = 0 ,0,

IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0 ,

SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1

,@le+1) ) levels

, @pathlevel:= CONCAT(@pathlevel,'|',code_value,':', @le ,'|') pathlevel

, @pathnodes:= IF( pid =0,',0',

CONCAT_WS(',',

IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,

SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1)

,@pathnodes ) ,pid ) )paths

,@pathall:=CONCAT(@pathall,'|',code_value,':', @pathnodes ,'|') pathall

FROM address,

(SELECT @le:=0,@pathlevel:='', @pathall:='',@pathnodes:='') vv

ORDER BY pid,code_value

) src

ORDER BY pid

--方法6  存储过程(SQL实现)

create procedure query_all_add_children(in inPid varchar(50))

begin

select id,code_value,name,remark,pid,p2id,p3id,p4id,p5id

from(

select a1.id,a1.code_value,a1.name,a1.remark,

a1.pid,a2.pid p2id,a3.pid p3id,a4.pid p4id,a5.pid p5id

from

address a1 left join address a2

on(a1.pid=a2.code_value)

left join address a3

on(a2.pid=a3.code_value)

left join address a4

on(a3.pid=a4.code_value)

left join address a5

on(a4.pid=a5.code_value)

) al

where

(pid=inPid

or p2id=inPid

or p3id=inPid

or p4id=inPid

or p5id=inPid

);

end

个人的一些理解:我是用的方法一:取出所有节点利用MySql函数截取所需要的字符串,然后在SQL中字段IN(调用此方法)来进行查询,这样效率比较高,方法6效率也较高,其他方法都有效率问题。

MySql/Oracle树形结构查询

Oracle树形结构递归查询 在Oracle中,对于树形查询可以使用start with ... connect by select * from treeTable start with id='1 ...

关于mysql中数据存储复合树形结构,查询时结果按树形结构输出

1.主要思想:根据已有数据,规则性的造数据 select * FROM(select lId,strName,lId as lParentId,-1 as orderIdx from tbClassi ...

【MySQL疑难杂症】如何将树形结构存储在数据库中(方案一、Adjacency List)

今天来看看一个比较头疼的问题,如何在数据库中存储树形结构呢? 像mysql这样的关系型数据库,比较适合存储一些类似表格的扁平化数据,但是遇到像树形结构这样有深度的人,就很难驾驭了. 举个栗子:现在有一 ...

Oracle树形结构查询(递归)

引用:https://blog.csdn.net/u012615705/article/details/78321022  文章转自上述地址,内部有稍许改动,如有需要请查看原文. oracle树状结构 ...

orcale 树形结构查询

接到需求是要在一个表中(表结构为主键id和父id)循环显示数据,类似于省市县++这种情况  也可能不只有三级子菜单 id  name   parentid 1     a          0 2  ...

Delphi中accesss实现树形结构查询系统(一次性生成比较方便)

主要是要读取数据库的信息,而delphi界面是一个树形结构. 例如有一个Ascess数据库:示例.MDB,内有一张表:“国家”,表的内容如下: 编号        名称  01             ...

sql:sql server,MySQL,PostgreSQL的表,视图,存储过程结构查询

sql server 2005: --SQL SERVER 2005 生成代码需要知道的SQL语句 use LibrarySystem --查询当前数据库所有表和其的主键字段,字段类型,长度,是否为空 ...

Oracle恢复删除数据 &;&; connect by 树形结构查询

1.一个表中根据以父子级别关系查询显示出来(如图) select t.* from department t CONNECT BY PRIOR t.depid=t.supdepid ; --这样也可以 ...

sql:MySQL 6.7 表,视图,存储过程结构查询

#数据库MySQL 6.7 use sakila; #查询表名 show tables; # SELECT TABLE_NAME,TABLE_ROWS FROM INFORMATION_SCHEMA. ...

随机推荐

js从数组中随机取出不同的元素

前言 上午处理个需求需要从一个总数组中随机取出不同的元素.共使用两个方法.第一种方法较常规,经测试有bug,数据量大以后随机几次返回的对象直接是function而不是object. 当然简单数据类型应 ...

java springMVC SSM 操作日志 4级别联动 文件管理 头像编辑 shiro redis

A 调用摄像头拍照,自定义裁剪编辑头像 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,开发利器)+快速构建表单;  技术:313596790freemaker模版技术 ,0个代码不用写 ...

【HTML5&;CSS3进阶学习02】Header的实现·CSS中的布局

前言 我们在手机上布局一般是这个样子的: 其中头部对整个mobile的设计至关重要,而且坑也很多: ① 一般来说整个header是以fixed布局,fixed这个产物在移动端来说本身坑就非常多 ② 在 ...

chrome内核浏览器input边框

直接给input加outline:none和设置input {outline:none}都没效 最后逼得没法,*:focus { outline: none; },然后整个世界就安静了,嚯嚯

Nutch的配置以及动态网站的抓取

http://blog.csdn.net/jimanyu/article/details/5619949 一:配置Nutch: 1.解压缩的nutch后,以抓取http://www.163.com/为 ...

line-height的小技巧

CSS中的line-height属性控制着文字的行间距离.通常被设置为一个无单位的值(例如:line-height:1.4),与文字尺寸是成比例的.它是排版中的一个重要的属性.太低了文字会挤在一起,太 ...

Java接口的表现形式

一.概念理解 Java接口是一些方法特征的集合,并没有方法的具体实现,类似于电源插座,可以充不同类型的电器,但是必须适配特定的接口规范.接口是抽象化的,所以其不能被实例化的(不能有构造函数,创建对象) ...

U盘做启动盘后,如何恢复原始容量

上次用U盘装系统后,U盘缩水1G多,格式化和快速格式化,没有用,无法恢复U盘原来的容量,后来在网上查到一个方法,成功释放U盘空间,故将恢复方法写在下面. (1)右击“我的电脑”,选择“管理”选项,之后 ...

STM32学习笔记——定时器中断(向原子哥学习)

定时器中断 STM32 的定时器功能十分强大,有 TIME1 和 TIME8 等高级定时器,也有 TIME2~TIME5 等通用定时器,还有 TIME6 和TIME7 等基本定时器.在本章中,我们将利 ...

Python基础入门教程,Python学习路线图

给大家整理的这套python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻的认识.或许可以喜欢上python这个易学,精简,开源的语言.此套教程,不但有视频教程,还有源码分享,让大 ...

你可能感兴趣的:(mysql查询树形结构子节点)