ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 【层次查询】Hierarchical Queries之处理顺序

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

Linux操作系统 作者:zoujb1314 时间:2015-05-04 21:21:14 0 删除 编辑
有关层次查询之前的文章参考如下。
【层次查询】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博客 ” ,链接:https://blog.itpub.net/29673710/viewspace-1622487/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-05-23

  • 博文量
    8
  • 访问量
    8348