Как упоминалось в комментариях @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 для обоих запросов
Подзапрос t1
генерирует список необходимых ингредиентов, а в колонке path2 - коэффициенты, которые нам нужно перемножить. t2
разворачивает эти значения, финальный запрос выполняет умножение и группирует результаты в случае, если было два полуфабриката, использующих одно и то же сырье. Для умножения я использовал ответ из этот ТАКОЙ вопрос.
person
Ponder Stibbons
schedule
04.11.2015