MySQL通过自定义函数实现递归查询父级ID或者子级ID
程序员文章站
2022-05-22 18:18:42
背 景: 在MySQL中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度, 那么所有节点为根的树的深度均不会超过树的最大深度,则我们可以直接通过left join来实现。 但很多时候我们是无法控制或者是知道树的深度的。这时就需要在MySQL中用存储过程(函数)来实现或者在程序中使用递归来实 ......
背 景:
在mysql中如果是有限的层次,比如我们事先如果可以确定这个树的最大深度, 那么所有节点为根的树的深度均不会超过树的最大深度,则我们可以直接通过left join来实现。
但很多时候我们是无法控制或者是知道树的深度的。这时就需要在mysql中用存储过程(函数)来实现或者在程序中使用递归来实现。本文讨论在mysql中使用函数来实现的方法:
一、环境准备
1、建表
1 create table `table_name` ( 2 `id` int(11) not null auto_increment, 3 `status` int(255) null default null, 4 `pid` int(11) null default null, 5 primary key (`id`) using btree 6 ) engine = innodb auto_increment = 1 character set = utf8 collate = utf8_general_ci row_format = dynamic;
2、插入数据
1 insert into `table_name` values (1, 12, 0); 2 insert into `table_name` values (2, 4, 1); 3 insert into `table_name` values (3, 8, 2); 4 insert into `table_name` values (4, 16, 3); 5 insert into `table_name` values (5, 32, 3); 6 insert into `table_name` values (6, 64, 3); 7 insert into `table_name` values (7, 128, 6); 8 insert into `table_name` values (8, 256, 7); 9 insert into `table_name` values (9, 512, 8); 10 insert into `table_name` values (10, 1024, 9); 11 insert into `table_name` values (11, 2048, 10);
二、mysql函数的编写
1、查询当前节点的所有父级节点
1 delimiter // 2 create function `getparentlist`(root_id bigint) 3 returns varchar(1000) 4 begin 5 declare k int default 0; 6 declare fid int default 1; 7 declare str varchar(1000) default '$'; 8 while rootid > 0 do 9 set fid=(select pid from table_name where root_id=id); 10 if fid > 0 then 11 set str = concat(str,',',fid); 12 set root_id = fid; 13 else 14 set root_id=fid; 15 end if; 16 end while; 17 return str; 18 end // 19 delimiter ;
2、查询当前节点的所有子节点
1 2 delimiter // 3 create function `getchildlist`(root_id bigint) 4 returns varchar(1000) 5 begin 6 declare str varchar(1000) ; 7 declare cid varchar(1000) ; 8 declare k int default 0; 9 set str = '$'; 10 set cid = cast(root_id as char);12 while cid is not null do 13 if k > 0 then 14 set str = concat(str,',',cid); 15 end if; 16 select group_concat(id) into cid from table_name where find_in_set(pid,cid)>0; 17 set k = k + 1; 18 end while; 19 return str; 20 end // 21 delimiter ;
三、测试
1、获取当前节点的所有父级
select getparentlist(10);
2、获取当前节点的所有字节
select getchildlist(3);
本文完......