|
嗯,必须承认小马哥的SQL有点难懂,我斗胆来给你的最新成果挑点毛病:
Select p,d,Sum(qty) From (
Select p,c,d,power(10,Sum(Log(10,qty))) As qty From (
Select Distinct P,c,SUBSTR(C,-1,1) D,regexp_substr(c,'[^,]+',1,Level), to_number(regexp_substr(Q,'[^*]+',1,Level)) As qty From (
Select CONNECT_BY_ROOT paret As P ,substr(SYS_CONNECT_BY_PATH(CHID,','),2) As C,1||SYS_CONNECT_BY_PATH(CQTY/PQTY,'*') As Q From tmp
Where CONNECT_BY_ISLEAF =1
Start With paret ='A'
Connect By paret = Prior CHID
) C
connect by Level<=length(regexp_replace(Q,'[^*]',''))+1
Order By 1,2
)tt
Group By p,c,d)ff
Group By p,d
这个SQL里面是把CQTY/PQTY逐层拼接然后又解析出来。碰巧例子中都是可以除尽的,如果碰上一个像 2/3 的你就有误差了。不如把CQTY和PQTY分开,最后算好总乘积再相除。
你在第三行有个SUBSTR(C,-1,1) D, 其实这个就是CHID, 你最好在最里层的SELECT多写一个CHID, 然后在有用到D的地方直接引用CHID。
你在第九行有个Level<=length(regexp_replace(Q,'[^*]',''))+1, 其实右边就是最里层的LEVEL, 你最好在最里层的SELECT多写一个LEVEL AS L, 这里改为Level<= L+1.
第十行来了个排序,完全无用。
最后,我不喜欢Level<=length(regexp_replace(Q,'[^*]',''))+1这样的写法,它的连接没有用到任何PRIOR条件,前后层完全无关,只要集合里行数稍多一点,右边的表达式稍微大一点,那么这个SELECT返回的行数就呈几何级数的上涨。虽然你后来用DISTINCT过滤掉了,但中间结果的开销可不小。 |
|