一个树形聚集SQL问题(二)
上一篇 / 下一篇 2008-07-15 23:27:58 / 个人分类:ORACLE
看到ITPUB上一个帖子,感觉楼主的需要比较有意思,于是尝试了一下。问题源自:http://www.itpub.net/thread-1020586-1-1.html
上一篇给出了一个SQL实现,不过由于不是很清楚楼主的含义,加上测试数据过于简单,没有将问题完全展现,因此第一篇给出的SQL并不能完全满足需要。这篇根据新的测试数据来构造求解的SQL。
一个树形聚集SQL问题(一):http://yangtingkun.itpub.net/post/468/466388
虽然上一篇给出的SQL能得到正确的结果,但是真正的情况比测试中要复杂很多,树形的分叉并非只可能存在于第一层,而是在任一层都可能包括多个叶节点。
比如插入一条记录:
SQL> SELECT * FROM T_LEVEL;
LEVELS PARENT CHILD PARENT_QTY CHILD_QTYITPUB个人空间R.f!utVb(B:M
---------- ---------- ---------- ---------- ----------ITPUB个人空间-MT0D&}x(ys
jN3_5E#A_6d0 2 B C 2 3ITPUB个人空间
Am;Na1q+Bx+e
|B7]U:{0w0 4 D E 1 2ITPUB个人空间8cf` DMQ0RKS
SQL> INSERT INTO T_LEVEL VALUES (4, 'D', 'F', 1, 3);
已创建1行。
SQL> SELECT P,
7POO`"K'U}0 2 SUBSTR(MAX(D), LENGTH(MAX(D))) C,ITPUB个人空间$fP_t`4n2e
3 POWER(10, SUM(LOG(10, Q))) QITPUB个人空间;y#^6hq.y2n8x
XA
4 FROMITPUB个人空间T*G"S\:|(ZME
5 (ITPUB个人空间G A'~#mN k
6 SELECT CONNECT_BY_ROOT(PARENT) P,
E{H
C9P)S0 7 SYS_CONNECT_BY_PATH(CHILD, '/') D,
"\?e`*? wf:X ]i2j0 8 CHILD_QTY/PARENT_QTY QITPUB个人空间ckrPrI0T
9 FROM T_LEVEL
(J;lln P8I1~0 10 START WITH LEVELS = 1ITPUB个人空间^'MDJ Y u-\9W
11 CONNECT BY PRIOR CHILD = PARENT
4[0e
}"Q9J,P z0 12 )
r
k+s7v;z!OOE'Qd9W0 13 GROUP BY P, SUBSTR(D, 2, 1);
P C QITPUB个人空间3qc
Bnkl
---------- ---------- ----------
8` Fi~+W0A F
现在得到的结果显然是不正确的,这里应该得到3条记录,A到E、A到F和A到Z。
虽然SQL得到的结果是不正确的,不过解题的思想并没有变,仍然是通过SUM解决连乘问题,通过构造来获取聚集的GROUP BY字段。
为了简单这个问题,可以将树形查询反过来进行,从所有的叶节点出发,汇总数据到根节点,具体实现SQL如下:
SQL> SELECTITPUB个人空间c7`h|1P%{&S,d
2 SUBSTR(MAX(D), INSTR(MAX(D), '/', -1) + 1) C,
!\X1Z&tp0 3 P,ITPUB个人空间3R%T*m3a\K2]
|!H\
4 POWER(10, SUM(LOG(10, Q))) QITPUB个人空间p*pyAe]
hF
5 FROM
Dt)l(w8F(u+^
~0 6 (ITPUB个人空间F6WG"yH)} @ @(J~
7 SELECT CONNECT_BY_ROOT(CHILD) P,
6_v.N9a8[u8T(v0 8 SYS_CONNECT_BY_PATH(PARENT, '/') D,
~
t|
pCir0 9 CHILD_QTY/PARENT_QTY QITPUB个人空间}6\:_3^ }2P$A:wV {
10 FROM T_LEVELITPUB个人空间{FB/@|9U(x[
11 START WITH CHILD IN
a$v hv)k9j'v4w1?^s3B/R0 12 (ITPUB个人空间1Z%I7o4pyl.C
13 SELECT CHILD FROM
?-KV&CYyqr0 14 (ITPUB个人空间
FTPjD5x,KU2pc
15 SELECT CHILD, CONNECT_BY_ISLEAF LEAF FROM T_LEVEL
ZM C.e(V LJH&e0 16 START WITH LEVELS = 1ITPUB个人空间"kzn
l#D9g.u.qhs
17 CONNECT BY PRIOR CHILD = PARENT
c2M|*GlX0 18 )ITPUB个人空间
RS7DaM\"W-B#[s
19 WHERE LEAF = 1ITPUB个人空间 @;{$Y+W4}
ae&}qNn
20 )ITPUB个人空间$l{0oE8oq\i
21 CONNECT BY PRIOR PARENT = CHILD
k:f%sx/@(Sf0 22 )ITPUB个人空间BT8~;\3|
23 GROUP BY P
5_"xq L/K,B0b)Q4px0 24 ;
C P QITPUB个人空间&R1e