ORACLE查询树型关系start with connect by prior

在oracle中的select语句可以用start with...connect by prior子句实现递归查询。其基本语法是:

select LEVEL,t.* from tablename t
where cond3
start with cond1
connect by cond2; 

注意:这里的where条件是放在tablename后面,如果放在cond2后面,执行查询报sql命令未正确结束的错误。

cond1:是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。 

cond2:是连接限定条件,格式为“PRIOR 列名1=列名2” 或 “列名1=PRIOR 列名2”。其中用prior表示上一条记录,比如connect by prior id=parentid就是说上一条记录的ID是本条记录的parentid,即本记录的父亲是上一条记录。 

cond3:是结果过滤条件,用于对返回的所有记录进行过滤(即在树查询出来后再进行过滤)。 

简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段: id,parent_id
那么可以通过该查询表示每一条记录的parent是谁,就可以形成一个树状结构。 

1、关于start with
START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的起始节点。若该子句被省略,则表示所有满足查询条件的行作为起始节点。不但可以指定一个起始节点,还可以指定多个起始节点。

2、 关于 PRIOR
在自顶向下查询树结构时,不但可以从根节点开始,还可以定义任何节点为起始节点,以此开始向下查找。这样查找的结果就是以该节点为开始的结构树的一枝。运算符 PRIOR 被放置于等号前后的位置,决定着查询时的检索顺序。
PRIOR 被置于 CONNECT BY 子句中等号的前面时,则强制从根节点到叶节点的顺序检索,即由父节点向子节点方向通过树结构,我们称之为自顶向下的方式。如:
CONNECT BY PRIOR EMPNO=MGR
PIROR 运算符被置于 CONNECT BY 子句中等号的后面时,则强制从叶节点到根节点的顺序检索,即由子节点向父节点方向通过树结构,我们称之为自底向上 的方式。例如:
CONNECT BY EMPNO=PRIOR MGR
在这种方式中也应指定一个开始的节点。

3、使用LEVEL
在具有树结构的表中,每一行数据都是树结构中的一个节点,由于节点所处的层次位置不同,所以每行记录都可以有一个层号。层号根据节点与根节点的距离确定。不论从哪个节点开始,该起始节点的层号始终为1 ,起始节点的子节点为2,依此类推。

4、节点和分支的裁剪
在对树结构进行查询时,可以去掉表中的某些行,也可以剪掉树中的一个分支,使用WHERE子句来限定树型结构中的单个节点,以去掉树中的单个节点,但它却不影响其后代节点(自顶向下检索时)或前辈节点(自底向顶检索时)。

5、排序显示
像在其它查询中一样,在树结构查询中也可以使用ORDER BY子句,改变查询结果的显示顺序,而不必按照遍历树结构的顺序。
--------------------------------------------------------------------------------

分割线

--------------------------------------------------------------------------------

上面简单介绍了oracle树结构查询语法,下面说明下实际应用中,因重复数据导致的特殊情况
 场景:一张表test_table中存储每个核心系统source,且每个source有自己专业机构id,每个专业机构下有相应的下级机构。但各个核心间的机构id存在重复。表数据如表1所示。

表1

idparent_idsource
2011核心1
1 核心1
20108201核心1
20108201核心2
2012核心2
2 核心2


表2

idparent_idsource
20108201核心1
2011核心1
1 核心1
2012核心2
2 核心2
20108201核心2
2011核心1
1 核心1
2012核心2
2 核心2

表3

idparent_idsource
20108201核心1
2011核心1
1 核心1
2011核心1
1 核心1

实际数据为核心1有专业机构为id=1,二级机构为id=201,三级机构为id=20108;核心2有专业机构为id=2,二级机构为id=201,三级机构为id=20108。

如果在不知道表内具体数据的情况下,直接使用以下语句从三级机构id=20108遍历查询其根节点,结果如表2所示。导致该原因是20108存在重复,201也存在重复,分别关联递归出多个树结构。

select * from test_table t
start with t.id = '20108'
connect by t.id = prior t.parent_id;

如果此时加上where条件,只查询核心系统1的三极机构id=20108对应的机构树结构。效果如表3所示。很明显where条件只是在表2的基础上进行再次筛选而已,结果不是我们想要的三级层次树结构。

select * from test_table t
where t.source = '核心1'
start with t.id = '20108'
connect by t.id = prior t.parent_id;

解决因不同核心数据重复导致关联出多个树结构问题,只需将限定条件加在start with和connect by上即可。具体SQL如下,效果详见表4。

select * from test_table t
start with (t.id = '20108' and t.source = '核心1')
connect by (t.id = prior t.parent_id and t.source = '核心1');

表4

idparent_idsource
20108201核心1
2011核心1
1 核心1

 

转载于:https://my.oschina.net/u/163737/blog/1475461

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值