有关层次查询之前的文章参考如下。
【层次查询】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 --
【层次查询】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/