以下是與我的真實場景類似的示例上下文。使用連接的分層查詢通過
產品:XYZ QTY:1
需要原料B,0.002
和半成品項目A,0.001
。生產我需要的原料J,0.1
和半成品K,0.9
。有產品K我以前我需要原材料G 0.004 enter code here
和T 0.005
。
我需要得到所需的全部原材料的累計產量10
產品數量XYZ
的結果。
以下是與我的真實場景類似的示例上下文。使用連接的分層查詢通過
產品:XYZ QTY:1
需要原料B,0.002
和半成品項目A,0.001
。生產我需要的原料J,0.1
和半成品K,0.9
。有產品K我以前我需要原材料G 0.004 enter code here
和T 0.005
。
我需要得到所需的全部原材料的累計產量10
產品數量XYZ
的結果。
試試這個:
SELECT component AS material, 10 * quantity AS quantity
FROM (SELECT component, quantity,
CASE WHEN CONNECT_BY_ISLEAF = 1 THEN 'Raw' ELSE 'Semi-Finished' END AS type
FROM bill_of_materials
START WITH item = 'XYZ' CONNECT BY PRIOR component = item)
WHERE type = 'Raw'
上SQL Fiddle的例子給出了:
J | 1
G | 0.04
T | 0.05
B | 0.02
之前,我不會繼續深入研究解決方案。我忘記了在樹上乘以因子。明天會重新考慮這一點。 –
正如@KenGeis在評論中提到,爲Oracle 11g中,您可以使用遞歸查詢:
with t (p, i , q) as (
select product, ingredient, qty from test where product = 'XYZ'
union all
select product, ingredient, qty*q from test, t where product = i)
select i, sum(q) qty from t
where not exists (select 1 from test where product = i) group by i;
如果由於某些原因您需要connect by
版本,這裏是我的嘗試:
with t1 as (
select ingredient i, sys_connect_by_path(ingredient, '/') path1,
sys_connect_by_path(qty, '/') path2
from test where connect_by_isleaf = 1 connect by prior ingredient = product
start with product = 'XYZ'),
t2 as (
select i, path1, path2, trim(regexp_substr(path2, '[^/]+', 1, lines.column_value)) val
from t1,
table (cast (multiset(
select level from dual connect by level < regexp_count(t1.path2, '/')+1
) as sys.ODCINumberList)) lines)
select i, sum(s) qty
from (select i, exp(sum(ln(val))) s from t2 group by i, path1) group by i
SQL Fiddle demo for both queries
子查詢t1
生成所需的原材料,並在列PATH2名單 - 這是我們需要乘以因素。 t2
未轉義這些值,如果 是兩個使用相同原材料的半成品,則最終查詢執行乘法和組結果。 對於乘法我用從this SO問題的答案。
解決方案是否需要使用CONNECT BY?遞歸的WITH子句將會更加自然。 –
我認爲這是一個很好的問題,但由於標題非常通用,而且問題很難閱讀,所以它已被低估。另外,在你澄清你是否真的需要使用CONNECT BY(即你使用Oracle小於11gR2?) –