Вы, вероятно, ищете что-то, что я покажу ниже. Обратите внимание, что аналитической c (и агрегатной) product
функции нет, мне пришлось ее смоделировать, взяв логи, аналитику c sum
и экспоненциальную функцию.
Я не понимаю, почему вы должны объединить productid и уровень (я назвал это "step") в одну строку; конечно, вы можете сделать это, если вы sh, но я показываю результаты так, как я считаю. Кроме того, в выводе не ясно, какой вес вы должны показать (или, скорее, ПОЧЕМУ) - вес до того, как продукт поступит в машину, или после того, как он будет обработан этой машиной? Я показываю оба (а также исходный вес до начала обработки) в каждом ряду; решите, что вам действительно нужно для вашего отчета.
Я смоделировал ваши входные данные в предложении WITH, но, конечно, вы должны использовать ваши фактические таблицы (с их именами таблиц и столбцов). Я надеюсь, что у вас есть таблица, как представление MACHINES в моем запросе. Я использовал левое внешнее соединение на тот случай, если машина фактически не отображается в таблице MACHINES, хотя это не должно быть разрешено. (Не уверен, как вы можете применить , что, хотя, учитывая вашу модель данных, которая является прямым нарушением первой нормальной формы.) Если машина не присутствует в таблице MACHINES, ее коэффициент доходности рассматривается как 1,00 в запрос. Это происходит с машиной 'M9' в этом примере.
with
sample_inputs (productid, currentweight, remainingroute) as (
select '001', 50, 'M1-M7-M5' from dual union all
select '002', 48, 'M3-M2-M9' from dual
)
, machines (machine, yield_factor) as (
select 'M1', 0.95 from dual union all
select 'M7', 0.90 from dual union all
select 'M3', 0.80 from dual union all
select 'M4', 1.00 from dual union all
select 'M6', 0.92 from dual union all
select 'M2', 0.90 from dual union all
select 'M5', 0.86 from dual
)
, routes (productid, step, currentweight, machine) as (
select productid, level, currentweight,
regexp_substr(remainingroute, '[^-]+', 1, level)
from sample_inputs
connect by level <= regexp_count(remainingroute, '[^-]+')
and prior productid = productid
and prior sys_guid() is not null
)
, weights (productid, step, original_weight, machine, weight_out) as (
select r.productid, r.step, r.currentweight, r.machine,
round(r.currentweight *
exp(sum(ln(m.yield_factor))
over (partition by r.productid order by r.step)), 2)
from routes r left outer join machines m on r.machine = m.machine
)
select productid, step, original_weight, machine,
lag(weight_out, 1, original_weight)
over (partition by productid order by step) as weight_in, weight_out
from weights
order by productid, step;
Вывод:
PRODUCTID STEP ORIGINAL_WEIGHT MACHINE WEIGHT_IN WEIGHT_OUT
---------- ---- --------------- ------- --------------- ---------------
001 1 50.00 M1 50.00 47.50
001 2 50.00 M7 47.50 42.75
001 3 50.00 M5 42.75 36.76
002 1 48.00 M3 48.00 38.40
002 2 48.00 M2 38.40 34.56
002 3 48.00 M9 34.56 34.56