Oracle递归查询

Sql代码
  1. create   table  TEST_TREE  
  2. (  
  3.   ID   NUMBER,  
  4.   PID  NUMBER,  
  5.   IND  NUMBER,  
  6.   NAME  VARCHAR2(32)  
  7. )  
create table TEST_TREE
(
  ID   NUMBER,
  PID  NUMBER,
  IND  NUMBER,
  NAME VARCHAR2(32)
)


    ID是主键,PID是父节点ID,IND是排序字段,NAME是节点名称。初始化几条测试数据。

 

IDPIDINDNAME
101根节点
211一级菜单1
312一级菜单2
412一级菜单3
521一级1子1
622一级1子2
741一级3子1
842一级3子2
943一级3子3
1040一级3子0

 

一、基本使用:

    在Oracle中,递归查询要用到start   with 。。。。connect   by   prior。。。

    具体格式是:

Sql代码
  1. SELECT   column   
  2. FROM  table_name  
  3. START WITH   column =value  
  4. CONNECT   BY   PRIOR  父主键=子外键  
SELECT column
FROM table_name
START WITH column=value
CONNECT BY PRIOR 父主键=子外键

    对于本例来说,就是:

Sql代码
  1. select    d.*    from   test_tree d   
  2.   start   with    d.pid=0  
  3.   connect     by     prior    d.id=d.pid   
select   d.*   from  test_tree d 
  start   with   d.pid=0
  connect   by   prior   d.id=d.pid 

   查询结果如下:

 

IDPIDINDNAME
101根节点
211一级菜单1
521一级1子1
622一级1子2
312一级菜单2
412一级菜单3
741一级3子1
842一级3子2
943一级3子3
1040一级3子0

 我们从结果中可以看到,记录已经是按照树形结构进行排列了,但是现在有个新问题,如果我们有这样的需求,就是不但要求结果按照树形结构显示,还要根据ind字段在每一个分支内进行排序,这个问题怎么处理呢?我们可能很自然的想到如下语句:

Sql代码
  1. select    d.*    from   test_tree d   
  2.   start   with    d.pid=0  
  3.   connect     by     prior    d.id=d.pid   
  4.   order   by  d.ind  
select   d.*   from  test_tree d 
  start   with   d.pid=0
  connect   by   prior   d.id=d.pid 
  order by d.ind

 结果如下:

 

IDPIDINDNAME
101根节点
211一级菜单1
521一级1子1
622一级1子2
412一级菜单3
1040一级3子0
842一级3子2
943一级3子3
741一级3子1
312一级菜单2

这显然不是我们想要的结果,那下面的这个语句呢?

Sql代码
  1. select    d.*    from   ( select  dd.*  from  test_tree dd  order   by  dd.ind) d   
  2.   start   with    d.pid=0  
  3.   connect     by     prior    d.id=d.pid   
select   d.*   from  (select dd.* from test_tree dd order by dd.ind) d 
  start   with   d.pid=0
  connect   by   prior   d.id=d.pid 

 

结果如下:

 

IDPIDINDNAME
101根节点
211一级菜单1
521一级1子1
622一级1子2
412一级菜单3
1040一级3子0
842一级3子2
943一级3子3
741一级3子1
312一级菜单2

这个结果看似对了,但由于一级菜单3节点下有一个节点的ind=0,导致一级菜单2被拍到了3下面。如果想使用类似这样的语句做到各分支内排序,则需要找到一个能够准确描述菜单级别的字段,但是对于示例表来说,不存在这么一个字段。

 

那我们如何实现需求呢?其实Oracle9以后,提供了一种排序“order siblings by”就可以实现我们的需求,用法如下:

Sql代码
  1. select    d.*    from   test_tree d   
  2.   start   with    d.pid=0  
  3.   connect     by     prior    d.id=d.pid   
  4.   order    siblings    by    d.ind    asc   
select   d.*   from  test_tree d 
  start   with   d.pid=0
  connect   by   prior   d.id=d.pid 
  order   siblings   by   d.ind   asc

 

结果如下:

 

IDPIDINDNAME
101根节点
211一级菜单1
521一级1子1
622一级1子2
312一级菜单2
412一级菜单3
1040一级3子0
741一级3子1
842一级3子2
943一级3子3

 

这样一来,查询结果就完全符合我们的要求了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值