oracle 递归查询一个树形结构的菜单

关键字:oracle connect by level 树状结构表
定义如下id 和 名称描述
1— 省长 <--- 2,3 (省长管辖市长、县长)
2— 市长 <--- 5,6 (市长管辖模范村村长和一个平民)
3— 县长 <--- 4,7,8,9 (县长管辖镇长和三个平民)
4— 镇长 <--- 10,11,12,13 (管辖四个平民)
5— 村长 <--- 14,15 (管辖两个平民)
其他(6-15)— 平民(没有管辖任何人)

只有 省长、市长县长能处理问题,那么每个人出了问题应该 首先找谁来解决?
省长权利最大,自己出了问题自己解决,别人也没法知道; 可以认为在关系表里省长的父节点是自己。
Db代码
  1. create table person(id int primary key, description varchar2(50));   
  2. create table relationship(child int, parent int, primary key(child,parent));   
  3. insert into person values(1,‘省长’);   
  4. insert into person values(2,‘市长’);   
  5. insert into person values(3,‘县长’);   
  6. insert into person values(4,‘镇长’);   
  7. insert into person values(5,‘村长’);   
  8. insert into person values(6,‘平民’);   
  9. ...//省略的都是平民   
  10. insert into person values(15,‘平民’);   
  11.   
  12. insert into relationship values(1,1); //关系如下   
  13. insert into relationship values(2,1);   
  14. insert into relationship values(3,1);   
  15. insert into relationship values(5,2);   
  16. insert into relationship values(6,2);   
  17. insert into relationship values(4,3);   
  18. insert into relationship values(7,3);   
  19. insert into relationship values(8,3);   
  20. insert into relationship values(9,3);   
  21. insert into relationship values(10,4);   
  22. insert into relationship values(11,4);   
  23. insert into relationship values(12,4);   
  24. insert into relationship values(13,4);   
  25. insert into relationship values(14,5);   
  26. insert into relationship values(15,5);  
create table person(id int primary key, description varchar2(50));
create table relationship(child int, parent int, primary key(child,parent));
insert into person values(1,‘省长’);
insert into person values(2,‘市长’);
insert into person values(3,‘县长’);
insert into person values(4,‘镇长’);
insert into person values(5,‘村长’);
insert into person values(6,‘平民’);
...//省略的都是平民
insert into person values(15,‘平民’);

insert into relationship values(1,1); //关系如下
insert into relationship values(2,1);
insert into relationship values(3,1);
insert into relationship values(5,2);
insert into relationship values(6,2);
insert into relationship values(4,3);
insert into relationship values(7,3);
insert into relationship values(8,3);
insert into relationship values(9,3);
insert into relationship values(10,4);
insert into relationship values(11,4);
insert into relationship values(12,4);
insert into relationship values(13,4);
insert into relationship values(14,5);
insert into relationship values(15,5);

查看一下关系树:
Oracle代码
  1. select rpad('---',(level-1)*3,'---')||child relation_tree   
  2. from relationship   
  3. start with child=parent   
  4. connect by nocycle prior child=parent; --结果如下   
  5. RELATION_TREE   
  6. ------------------   
  7. 1  
  8. ---2  
  9. ------5  
  10. ---------14  
  11. ---------15  
  12. ------6  
  13. ---3  
  14. ------4  
  15. ---------10  
  16. ---------11  
  17. ---------12  
  18. ---------13  
  19. ------7  
  20. ------8  
  21. ------9  
  22.   
  23. 已选择15行。  
select rpad('---',(level-1)*3,'---')||child relation_tree
from relationship
start with child=parent
connect by nocycle prior child=parent; --结果如下
RELATION_TREE
------------------
1
---2
------5
---------14
---------15
------6
---3
------4
---------10
---------11
---------12
---------13
------7
------8
------9

已选择15行。

查看父子关系情况:
Oracle代码
  1. select child,parent   
  2. from relationship   
  3. start with child=parent   
  4. connect by nocycle prior child=parent   
  5. order by parent; --结果如下   
  6.  CHILD     PARENT   
  7. ---------- ----------   
  8.          1          1  
  9.          2          1  
  10.          3          1  
  11.          5          2  
  12.          6          2  
  13.          4          3  
  14.          8          3  
  15.          7          3  
  16.          9          3  
  17.         11          4  
  18.         12          4  
  19.         10          4  
  20.         13          4  
  21.         14          5  
  22.         15          5  
  23.   
  24. 已选择15行。  
select child,parent
from relationship
start with child=parent
connect by nocycle prior child=parent
order by parent; --结果如下
 CHILD     PARENT
---------- ----------
         1          1
         2          1
         3          1
         5          2
         6          2
         4          3
         8          3
         7          3
         9          3
        11          4
        12          4
        10          4
        13          4
        14          5
        15          5

已选择15行。

下面要看一看:每个人有事时,首先找到谁来处理?不能每个人有事都找省长吧。
下面的sql使用了oracle家的两个变态函数:first_value & connect_by_root
Oracle代码
  1. select distinct child ,first_value(parent)over(partition by child order by lv) parent   
  2. from(   
  3.     select connect_by_root(r.child) child, p.description descr, level lv, r.parent   
  4.     from person p ,relationship r   
  5.     where p.id= r.parent   
  6.     connect by nocycle prior r.parent=r.child   
  7.  )   
  8. where descr in('省长''市长''县长')   
  9. order by parent,child; --结果如下   
  10.      CHILD     PARENT   
  11. ---------- ----------   
  12.          1          1  
  13.          2          1  
  14.          3          1  
  15.          5          2  
  16.          6          2  
  17.         14          2  
  18.         15          2  
  19.          4          3  
  20.          7          3  
  21.          8          3  
  22.          9          3  
  23.         10          3  
  24.         11          3  
  25.         12          3  
  26.         13          3  
  27.   
  28. 已选择15行。  
select distinct child ,first_value(parent)over(partition by child order by lv) parent
from(
    select connect_by_root(r.child) child, p.description descr, level lv, r.parent
 	from person p ,relationship r
 	where p.id= r.parent
 	connect by nocycle prior r.parent=r.child
 )
where descr in('省长', '市长', '县长')
order by parent,child; --结果如下
     CHILD     PARENT
---------- ----------
         1          1
         2          1
         3          1
         5          2
         6          2
        14          2
        15          2
         4          3
         7          3
         8          3
         9          3
        10          3
        11          3
        12          3
        13          3

已选择15行。

这个sql到底行不行,再加条数据看看
Db代码
  1. insert into person values(333,‘县长’);   
  2. insert into person values(555,‘村长’);   
  3. insert into person values(666,‘平民’);    
  4. insert into person values(777,‘平民’);   
  5.   
  6. insert into relationship values(333,1);   
  7. insert into relationship values(555,333);   
  8. insert into relationship values(666555);   
  9. insert into relationship values(777,666);   
  10.               --666这个平民有¥,777愿意跟着他(这条记录比较特殊)  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值