oracle ---递归查询(start with --connect by prior )

递归查询要处理的问题:树形结构数据,存储在一张表中,然后通过start with --connect by prior-来进行遍历

示例基础:

create table a_test

( p_id  varchar2(10),

   id    varchar2(10));

insert into a_test values ( '', '1' );
insert into a_test values ( '1', '2' );
insert into a_test values ( '1', '3' );
insert into a_test values ( '2', '4' );
insert into a_test values ( '2', '5' );
insert into a_test values ( '3', '6' );
insert into a_test values ( '3', '7' );
insert into a_test values ( '5', '8' );
insert into a_test values ( '5', '9' );
insert into a_test values ( '7', '10' );
insert into a_test values ( '7', '11' );
insert into a_test values ( '10', '12' );
insert into a_test values ( '10', '13' );
SELECT * FROM a_test


数据结构图


给出一个节点根据节点查询,节点一下的数据如

例1:SELECT  ID ,P_ID ,LEVEL FROM a_test  START WITH P_ID = 3 CONNECT BY PRIOR ID  = P_ID


根据返回的结果集可以看出,通过这个语句,我们得到了3节点以下的所有值(没有包含3这条数据

所以,START WITH 后跟的条件为查询的树形结构的起始节点;

 CONNECT BY  后跟的就是遍历的条件;

关键字 PRIOR 就定义了遍历的方向,若是PRIOR与父级字段一起则向上查询,与子级字段则向下查询 

向上查询:例2:SELECT  ID ,P_ID ,LEVEL FROM a_test  START WITH P_ID = 3 CONNECT BY ID  = PRIOR P_ID


向下查询:见例1;

where子句放在strat with之前,否则会报错

SELECT  ID ,P_ID ,LEVEL FROM a_test where LEVEL in (1,2) START WITH ID = 3 CONNECT BY PRIOR ID  =  P_ID

start with 嵌套使用,若是有这样需求时,给出一个子节点的值,要求查出该子节点父节点之下的所有值,

此时我想到的就是使用两次递归查询一次查询出当前子节点的父节点,然后以父节点为跟查询父节点下的所有值

嵌套使用

select ID ,P_ID,LEVEL 
FROM  a_test 
START WITH ID IN (SELECT  ID 
                 FROM a_test 
                 where LEVEL = 2 
                 START WITH ID = 7 
                 CONNECT BY  ID  =  PRIOR P_ID )
CONNECT BY PRIOR ID  =   P_ID  

 这样虽然能实现需求,但是这样查询的效率很低,怀疑是在递归查询的过程中子查询会反复执行

用with语句来解决

WITH temp  as (SELECT  ID 
                 FROM a_test 
                 where LEVEL = 2 
                 START WITH ID = 7 
                 CONNECT BY  ID  =  PRIOR P_ID)
select ID ,P_ID,LEVEL 
FROM  a_test 
START WITH ID IN (select * from  temp)
CONNECT BY PRIOR ID  =   P_ID

这样先吧子查询查出来,然后再进行另一个递归查询

(ps:数据量稍微多就会产生明显的差距,具体原因么有查询出来,之前的判断仅为猜测!)  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值