原文链接:Click Here
在些这篇文章之前我也在STEP DAY内查询了一下关于oracle递归查询的问题有人也写了一篇文章,地址是:http://www.stepday.com/topic/?175 文章内说得很粗糙,今天我就个人经验来细聊一下递归查询start with 条件1 connect by prior 条件2的问题。
首先假设我们这样一张具有层次结构的数据表t_user,简单的数据结构如下所示:
ID | NAME | PARENTID |
101 | 用户1 | 0 |
102 | 用户2 | 101 |
103 | 用户3 | 102 |
如果我们用一颗树来展现用户1、用户2、用户3三者之间的关系,树形结构如下所示:
1.
|-用户1
2.
---|-用户2
3.
-----|-用户3
提出问题:
1、知道用户1的ID,如何获得以用户1作为根节点的这棵用户树列表?
2、知道用户2的ID,如何获得其父节点上的所有用户列表?
3、知道用户1的ID,如何获得其所有子节点的用户列表且不包含ID=102的用户?
如果不知道如何使用oracle内递归脚本的童鞋遇到这样一些问题可能就只能够靠程序来遍历列表获得结果集了。首先通过sql获得所有的用户列表,然后在后台程序中对其进行遍历处理,变相地得到结果。虽然结果一样但是后者的效率就差了十万八千里了,数据量不大的情况下倒是看不出什么差距,一单数据量起来后数据库脚本处理和程序逻辑处理的效率差距就很明显了。
那么oracle内有可以直接使用的递归查询脚本吗?答案是肯定的,oracle如此牛逼也不是白牛的撒!那我们就一起来认识认识递归查询常用脚本吧!
1.
start
with
条件1 connect by prior 条件2
脚本解读:
1、start with 后面跟着的“条件1”是必须要有的,而且是作为最初的查询条件也是起始过滤条件;
2、connect by prior 后面跟着的“条件2”是其次查询过滤条件,用于控制递归查询的方向是向上递归还是向下递归。
3、常结合的脚本查询形式如下所示:
select *
from 表名
where 条件1
start with 条件2
connect by prior 当前表字段=级联表字段
start with与connect by prior语句完成递归记录,形成一棵树形结构,通常可以在具有层次结构的表中使用。
start with表示开始的记录
connect by prior 指定与当前记录关联时的字段关系
解决实际问题的能力:
现在我们就来看看这个递归查询脚本解决问题的实际能力如何?分别用sql脚本来解决最先提出的三个问题:
1、
1.
select
* from t_user start with ID = 101 connect by prior ID = PARENTID;
表示先获得ID=101的记录,然后再逐层查找其记录内的PARENTID为当前ID的记录,就这样依次循环的向下遍历;
2、
1.
select
* from t_user start with ID = 102 connect by prior PARENTID = ID;
表示先获得ID=102的记录,然后逐层查找其记录内的ID为当前PARENTID的记录,就这样依次循环的向上遍历;
3、
1.
select
* from t_user
where
ID <> 102 start with = 101 connect by prior ID = PARENTID;
首先过滤掉ID=102的记录,接着先获得ID=101的记录,然后再逐层查找其记录内的PARENTID为当前ID的记录,就这样依次循环的向下遍历;
我想通过这样深刻地讲述,大家能够更深入地理解start with connect by prior的原理。
如果有什么不太清楚和明白的地方,欢迎留言讨论!让我们一道感受oracle的强大魅力!