pub上有个帖子,讲connect by, 参见这里
觉得有点意思,以前也是没有深入考虑研究过这个东西,现在测试下看看....
createtable test_connect(flag varchar2(2));
insertinto test_connect values('A');
insertinto test_connect values('B');
commit;
insertinto test_connect values('A');
insertinto test_connect values('B');
commit;
select
flag, levelas lev
from test_connect
connect by level < 4;
FLAG LEV
---- ----------
A 1
A 2
A 3
B 3
B 2
A 3
B 3
B 1
A 2
A 3
B 3
B 2
A 3
B 3
14 rows selected.
flag, levelas lev
from test_connect
connect by level < 4;
FLAG LEV
---- ----------
A 1
A 2
A 3
B 3
B 2
A 3
B 3
B 1
A 2
A 3
B 3
B 2
A 3
B 3
14 rows selected.
仔细瞅瞅上面的结果,可以看出来其实生成的是两棵树(根节点分别为'A' 和 'B'), 如下图所示...
因为没有对A和B做特殊的处理,因此A和B可以作为任意节点(包括“他自己”)的子节点,所以也就会出现类似于(A->A->A)这样的路径信息。
可以借助如下的语句来显示path的信息...
select rownum,
level,
sys_connect_by_path( flag, '->') path,
flag,
connect_by_isleaf isleaf,
connect_by_root flag as root
from test_connect
connect by nocycle level<4
orderby rownum, level, path
level,
sys_connect_by_path( flag, '->') path,
flag,
connect_by_isleaf isleaf,
connect_by_root flag as root
from test_connect
connect by nocycle level<4
orderby rownum, level, path
从root列可以明显看出是有两棵树的, 根节点分别是A和B。
帖子的楼主给出了一个关于节点数的公式,很是强大....
================================================
无需多说,我们很快可以找到其中的规律,假设表中有N条记录
则记F(N,l)为 select id,level from t connect by level<l 的结果集数目
那么,
F(N,1)=N
F(N,l) = F(N,l-1)*N+N
于是可以总结出
F(N,l)=∑power(N,p), p取值为[1,l)
====================================================
因此对于我这个两条记录('A', 'B'), 层次为3的例子来说, 节点数(结果行数)为 2+2*2+2*2*2 = 14