下面是示例上下文,与我的实际情况类似。
产品:XYZ QTY:1
需要原材料B,0.002
和半成品A,0.001
。生成我需要的原材料J,0.1
和半成品K,0.9
。在我需要原材料G 0.004 enter code here
和T 0.005
。
我需要获得总需要所有原材料的结果及其累计数量,以便在产品数量10
中生成XYZ
。
答案 0 :(得分:1)
试试这个:
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
答案 1 :(得分:1)
正如@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
生成所需原始成分的列表,以及列路径2 - 我们需要乘以的因子。
t2
unpivots 这些值,最终查询执行乘法和组结果以防万一
是两个使用相同原料的半成品。
对于乘法,我使用了来自this SO问题的答案。