树形结构_数据库_利用递归遍历一棵只知道父节点的树
2016-02-26 10:38
567 查看
今天头提了一个需求,要求 求一棵只知道父节点的树下有多少叶子节点,叶子节点有可能挂在中间节点上。
(怕说的不明确:求一个部门下的所有人,部门下可能有子部门,一级部门下有人,二级部门下也可能有人。
已知条件:1.已知人所属的部门 2.知道部门的父节点 3.部门节点的层数(无用))
我的设计思想: 希望有其他思路的同学可以踊跃发言,谢谢
1.利用广搜的思路,额外开辟一个空间记录哪些部门节点被遍历了。
2.将该节点下所有的子节点加入到额外空间中,并标识为未访问。
3.将该节点下的所有人加入到总人数中,将该节点标识为已访问。
4.直到所有节点标识显示都被访问。(所有都被访问表示树被遍历完成,因为:新加入的节点都是未访问的)
下面以SQL中的存储过程的形式 给出答案
不熟悉存储过程的同学可以参看我的存储过程讲解,传送门:http://blog.csdn.net/u010003835/article/details/50496904
(怕说的不明确:求一个部门下的所有人,部门下可能有子部门,一级部门下有人,二级部门下也可能有人。
已知条件:1.已知人所属的部门 2.知道部门的父节点 3.部门节点的层数(无用))
我的设计思想: 希望有其他思路的同学可以踊跃发言,谢谢
1.利用广搜的思路,额外开辟一个空间记录哪些部门节点被遍历了。
2.将该节点下所有的子节点加入到额外空间中,并标识为未访问。
3.将该节点下的所有人加入到总人数中,将该节点标识为已访问。
4.直到所有节点标识显示都被访问。(所有都被访问表示树被遍历完成,因为:新加入的节点都是未访问的)
下面以SQL中的存储过程的形式 给出答案
不熟悉存储过程的同学可以参看我的存储过程讲解,传送门:http://blog.csdn.net/u010003835/article/details/50496904
DROP PROCEDURE IF EXISTS calShouldNum; -- 计算某个部门下的应到人数 CREATE PROCEDURE calShouldNum( IN parent_dep_id INT(40), INOUT should_num INT ) BEGIN -- 存储过程说明: -- 计算某部门的应到人数,利用递归完成。 DECLARE total_num INT DEFAULT 0; DECLARE tmp_dep_id INT(40) DEFAULT 0; DECLARE tmp_count INT DEFAULT 0; -- 临时表,相当于广搜的队列(需要多次使用) CREATE TABLE IF NOT EXISTS tmpCalShouldTable ( department_num INT(40), should_mark INT DEFAULT 0 ); -- 设置系统递归层数 set max_sp_recursion_depth=254; -- 计算还未被访问并递归的部门数量 SELECT COUNT(tmpCalShouldTable.department_num) FROM tmpCalShouldTable WHERE should_mark = 0 INTO tmp_count; -- 若还有节点没有被访问 WHILE tmp_count <> 0 DO -- 1.找到第一个没有被遍历的节点 SELECT department_num FROM tmpCalShouldTable WHERE tmpCalShouldTable.should_mark = 0 LIMIT 1 OFFSET 0 INTO tmp_dep_id; -- 2.查找当前节点有多少人,并累加到应到人数中 SELECT COUNT(u_info.user_id) FROM user_info u_info WHERE u_info.department_id = tmp_dep_id INTO total_num; SET should_num = total_num + should_num; UPDATE tmpCalShouldTable SET should_mark = 1 WHERE department_num = tmp_dep_id; -- 3.将当前部门下的所有子部门加到临时表中 INSERT INTO tmpCalShouldTable(department_num) SELECT u_dep.department_num FROM user_department u_dep WHERE u_dep.parent_id = parent_dep_id; -- 4.查找第一个未被访问的子节点,并递归 SELECT department_num FROM tmpCalShouldTable WHERE tmpCalShouldTable.should_mark = 0 LIMIT 1 OFFSET 0 INTO tmp_dep_id; CALL calShouldNum(tmp_dep_id, should_num); -- 计算还未被访问并递归的部门数量 SELECT COUNT(tmpCalShouldTable.department_num) FROM tmpCalShouldTable WHERE should_mark = 0 INTO tmp_count; END WHILE; END;
相关文章推荐
- Oracle11.2新增GLOBAL AWR报告
- 安装sql server 2000
- 【SQL Server】统计信息实战+实用SQL语句
- MySQL 加锁处理分析
- mysql-常用命令
- oracle 数据库的常用查询对象
- mac 装 mongodb
- 在Linux上安装Memcached服务
- Postgresql的并发(一)
- mysql子查询
- 根据字段条件清理mysql数据库数据
- mysql复制表的操作
- Redis学习--KEY操作命名
- MySQL 高可用架构在业务层面细化分析研究
- oracle子查询
- mysql数据库的三范式的设计与理解
- postgressql数据库给模式添加search_path
- 答:SQLServer DBA 三十问之六:Job信息我们可以通过哪些表获取;系统正在运行的语句可以通过哪些视图获取;如何获取某个T-SQL语句的IO、Time等信息;
- oracle的基操作
- sql统计各科不及格的人数,要求查询结果是一行