【层次查询】Hierarchical Queries之处理顺序

有关层次查询之前的文章参考如下。
【层次查询】Hierarchical Queries之“树的遍历”
http://space.itpub.net/519536/viewspace-623809
【层次查询】Hierarchical Queries之LEVEL应用
http://space.itpub.net/519536/viewspace-623916
【层次查询】Hierarchical Queries之CONNECT_BY_ISCYCLE伪列
http://space.itpub.net/519536/viewspace-624032
【层次查询】Hierarchical Queries之CONNECT_BY_ISLEAF伪列
http://space.itpub.net/519536/viewspace-624075
【层次查询】Hierarchical Queries之SYS_CONNECT_BY_PATH函数
http://space.itpub.net/519536/viewspace-624099
【层次查询】Hierarchical Queries之寻根问祖(CONNECT_BY_ROOT一元运算符)
http://space.itpub.net/519536/viewspace-624114
【层次查询】Hierarchical Queries之亲兄弟间的排序(ORDER SIBLINGS BY)
http://space.itpub.net/519536/viewspace-624176

如若对层次查询中的诸多条件的处理顺序不清楚的话,在某些情况下可能会得到一些意想不到的数据结果,理解层次查询的处理顺序刻不容缓。
本文会先给出一个容易误解的例子,然后会给出层次查询处理顺序的一般原则。

1.回望关系“树”,注意力请集中在第三层的D和E。
      A
     / \
    B   C
   /   /
  D   E
 / \
F   G

2.重温一下阐述上图的T表数据
sec@ora10g> select * from t;

X                   Y          Z
---------- ---------- ----------
A                   1
B                   2          1
C                   3          1
D                   4          2
E                   5          3
F                   6          4
G                   7          4

7 rows selected.

3.先看一下“level != 3”这个条件在where子句和connect by子句中各自的效果。后面会给出差异原因。
1)不加限制条件,以A为根节点的全貌如下。
sec@ora10g> col tree for a16
sec@ora10g> col tree_path for a16
sec@ora10g> select lpad(' ',level-1)||x tree, SYS_CONNECT_BY_PATH(x,'/') tree_path, level from t start with x = 'A' connect by prior y=z;

TREE             TREE_PATH             LEVEL
---------------- ---------------- ----------
A                /A                        1
 B               /A/B                      2
  D              /A/B/D                    3
   F             /A/B/D/F                  4
   G             /A/B/D/G                  4
 C               /A/C                      2
  E              /A/C/E                    3

7 rows selected.

2)条件“level != 3”在where子句时的效果
sec@ora10g> select lpad(' ',level-1)||x tree, SYS_CONNECT_BY_PATH(x,'/') tree_path, level from t where level != 3 start with x = 'A' connect by prior y=z;

TREE             TREE_PATH             LEVEL
---------------- ---------------- ----------
A                /A                        1
 B               /A/B                      2
   F             /A/B/D/F                  4
   G             /A/B/D/G                  4
 C               /A/C                      2

3)条件“level != 3”在connect by子句时的效果
sec@ora10g> select lpad(' ',level-1)||x tree, SYS_CONNECT_BY_PATH(x,'/') tree_path, level from t start with x = 'A' connect by prior y=z and level != 3;

TREE             TREE_PATH             LEVEL
---------------- ---------------- ----------
A                /A                        1
 B               /A/B                      2
 C               /A/C                      2

4)比较结果
当“level != 3”条件在where子句时,我们可以看到结果仅仅是将第三层的D和E过滤掉了。
然而,当“level != 3”条件在connect by子句时,我们发现第三层及其之后的节点数据全部被过滤掉了。

4.缘由--层次查询的处理顺序
根本原因在于层次查询中的语句处理顺序,包含层次查询的SQL的处理顺序如下:
首先处理:FROM和WHERE子句中连接条件
其次处理:START WITH子句
再次处理:CONNECT BY子句
最后处理:非连接条件的WHERE子句

本例中用到了后三种子句,因此当“level != 3”条件在where子句时,因为start with和connect by子句先被处理,因此整棵树会先被构造出来,在这个树的基础上再处理where子句中的限制条件,所以结果仅仅去掉了第三层节点数据。
然而当条件“level != 3”在connect by子句时,由于先对connect by子句进行处理,导致第三层及之后的数据全部被过滤掉了,因此只剩下第一层和第二层的节点数据。

5.小结
深谙层析查询的处理顺序是得到正确查询结果的前提,本文只是抛一小砖,点到为止,更多的收获来自实践的积累。

Good luck.

secooler
10.01.04

-- The End --



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/519536/viewspace-624276/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/519536/viewspace-624276/

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值