MySQL用存储过程实现递归查询(一)

 
  
1 drop table if exists employee;
2
3 create table employee
4 (
5 emp_id smallint unsigned not null auto_increment primary key ,
6 name varchar ( 32 ) not null ,
7 boss_id smallint unsigned null ,
8 key boss_id_idx(boss_id)
9 )engine = innodb;
10
11
12 insert into employee (name, boss_id) values
13 ( ' foo ' , null ),
14 ( ' ali later ' , 1 ), ( ' megan fox ' , 1 ),
15 ( ' jessica alba ' , 2 ), ( ' eva longoria ' , 2 ),
16 ( ' keira knightley ' , 3 ), ( ' liv tyler ' , 3 ),
17 ( ' sophie marceau ' , 5 );
18
19
20 delimiter ;
21
22 drop procedure if exists employee_hier;
23
24 delimiter #
25
26 create procedure employee_hier
27 (
28 in p_emp_id smallint unsigned
29 )
30 begin
31
32 declare p_done tinyint unsigned default ( 0 );
33 declare p_depth smallint unsigned default ( 0 );
34
35 create temporary table hier(
36 boss_id smallint unsigned,
37 emp_id smallint unsigned,
38 depth smallint unsigned
39 )engine = memory;
40
41 insert into hier values ( null , p_emp_id, p_depth);
42
43 /* http://dev.mysql.com/doc/refman/5.0/en/temporary-table-problems.html */
44
45 create temporary table emps engine = memory select * from hier;
46
47 while p_done <> 1 do
48
49 if exists ( select 1 from employee e inner join hier on e.boss_id = hier.emp_id and hier.depth = p_depth) then
50
51 insert into hier select e.boss_id, e.emp_id, p_depth + 1
52 from employee e inner join emps on e.boss_id = emps.emp_id and emps.depth = p_depth;
53
54 set p_depth = p_depth + 1 ;
55
56 truncate table emps;
57 insert into emps select * from hier where depth = p_depth;
58
59 else
60 set p_done = 1 ;
61 end if ;
62
63 end while ;
64
65 select
66 e.emp_id,
67 e.name as emp_name,
68 b.emp_id as boss_emp_id,
69 b.name as boss_name,
70 hier.depth
71 from
72 hier
73 inner join employee e on hier.emp_id = e.emp_id
74 inner join employee b on hier.boss_id = b.emp_id;
75
76 drop temporary table if exists hier;
77 drop temporary table if exists emps;
78
79 end #
80
81 delimiter ;
82
83 /*
84
85 select * from employee;
86
87 emp_id name boss_id
88 ====== ==== =======
89 1 foo null
90 2 ali later 1
91 3 megan fox 1
92 4 jessica alba 2
93 5 eva longoria 2
94 6 keira knightley 3
95 7 liv tyler 3
96 8 sophie marceau 5
97
98 call employee_hier(1);
99
100 emp_id emp_name boss_emp_id boss_name depth
101 ====== ======== =========== ========= =====
102 2 ali later 1 foo 1
103 3 megan fox 1 foo 1
104 4 jessica alba 2 ali later 2
105 5 eva longoria 2 ali later 2
106 6 keira knightley 3 megan fox 2
107 7 liv tyler 3 megan fox 2
108 8 sophie marceau 5 eva longoria 3
109
110 call employee_hier(3);
111
112 emp_id emp_name boss_emp_id boss_name depth
113 ====== ======== =========== ========= =====
114 6 keira knightley 3 megan fox 1
115 7 liv tyler 3 megan fox 1
116 */
摘自国外网站:http://pastie.org/1056977

转载于:https://www.cnblogs.com/sunss/archive/2011/06/14/2080617.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 存储过程是一种在 MySQL 数据库存储并执行 SQL 语句的方法。MySQL 存储过程可以使用递归技术来处理一些需要对同一数据进行多次处理的问题,比如树形结构的遍历、图形结构的遍历等。下面是一个使用 MySQL 存储过程实现递归的示例: 首先,我们需要创建一个表,用于存储树形结构的数据。假设这个表名为 `tree`,包含如下字段: ``` id INT PRIMARY KEY, name VARCHAR(255), parent_id INT ``` 其中,`id` 是节点的唯一标识符,`name` 是节点的名称,`parent_id` 是节点的父节点标识符。如果一个节点没有父节点,则其 `parent_id` 为 NULL。 接下来,我们可以创建一个存储过程,用于从指定的节点开始遍历整个树形结构。这个存储过程包含两个参数:起始节点的 `id` 和当前节点的深度。 ``` CREATE PROCEDURE traverse_tree (IN start_id INT, IN depth INT) BEGIN DECLARE done INT DEFAULT FALSE; DECLARE cur_id INT; DECLARE cur_depth INT; -- 创建一个游标,查询当前节点的所有子节点 DECLARE cur CURSOR FOR SELECT id FROM tree WHERE parent_id = start_id; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; -- 遍历所有子节点 OPEN cur; read_loop: LOOP FETCH cur INTO cur_id; IF done THEN LEAVE read_loop; END IF; -- 处理当前节点 SET cur_depth = depth + 1; SELECT CONCAT(REPEAT(' ', depth), name) FROM tree WHERE id = cur_id; -- 递归处理当前节点的子节点 CALL traverse_tree(cur_id, cur_depth); END LOOP; CLOSE cur; END; ``` 这个存储过程使用游标查询当前节点的所有子节点,并递归调用自己处理子节点。它还使用了一个 `depth` 参数,用于记录当前节点的深度,以便输出时缩进一定的空格。 我们可以调用这个存储过程,从指定的节点开始遍历树形结构。 ``` CALL traverse_tree(1, 0); ``` 其中,`1` 是起始节点的 `id`,`0` 是起始节点的深度(根节点的深度为 0)。这个存储过程将会输出整个树形结构的层次结构。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值