У меня довольно сложная проблема, которую я пытался решить в течение последних нескольких дней.В настоящее время я решаю ее с помощью предложения Oracle SQL Model и, возможно, мог бы написать функцию, но я ищу хорошее простое решение с использованием аналитических функций или чего-то еще, но ничего не могу понять.
Для данногополитика (ddpsid), я хочу суммировать столбец вычетов (ddddpc).[Извините за сложные названия столбцов, они не мои].Звучит просто, но если столбец ddbnep имеет значение «Y», то я хочу подвести итог всех предыдущих вычетов и взять текущий вычет как процент от того, что уже было вычтено.Итак, если текущий вычет составляет 10%, а предыдущие вычеты составляют 20% (т. Е. Осталось 80%), то я хочу вычесть 8% (10% или 80%), в общей сложности 28%.
Код ниже - это то, что я сейчас использую:
with my_sample_data as (
select 1 as ddpsid, ddddsq, ddddpc, ddbnep, ddadep
from (
select 1 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
select 2 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual union all
select 3 as ddddsq, 10 as ddddpc, 'N' as ddbnep, 'Y' as ddadep from dual union all
select 4 as ddddsq, 10 as ddddpc, 'Y' as ddbnep, 'Y' as ddadep from dual
)
)
-- select
-- ddpsid,
-- cumul as ddddpc
-- from (
select
ddpsid,
ddddsq,
ddadep,
ddbnep,
ddddpc,
rn,
num_rows,
100 * (1-cumul) as cumul
from my_sample_data a
where ddadep = 'Y'
model
return all rows
partition by (ddpsid)
dimension by (row_number() over(partition by ddpsid order by ddddsq) as rn)
measures (ddddsq, ddadep, ddddpc, ddbnep, 0 as cumul,
count(*) over(partition by ddpsid) as num_rows)
rules automatic order (
cumul[rn] = case
when nvl(ddbnep[cv(rn)],'N') = 'N'
then nvl(cumul[cv(rn)-1],1)- ddddpc[cv(rn)] /100
else nvl(cumul[cv(rn)-1],1)* (1- ddddpc[cv(rn)]/100) end
)
-- )
-- where rn = num_rows
Данные должны быть сгруппированы по ddpsid и обработаны в порядке ddddsq.Комбинация ddpsid и ddddsq должна быть уникальной.Процент удержания находится в столбце ddddpc.Я только хочу обрабатывать строки, где ddadep = 'Y'.И, наконец, если столбец ddbnep = 'N', то я хочу просто добавить ddddpc к итоговой сумме, в противном случае, если ddbnep = 'Y', я хочу взять ddddpc в процентах (100% - промежуточная сумма) и добавить егок итоговой сумме.
Код, закомментированный, необходим, потому что я действительно хочу только последнее значение для каждого ddpsid, но оно показывает работу немного лучше без этого.
Извините за длинный вопросно это самое краткое описание, которое я могу предоставить.
Приведенный выше код показывает четыре вычета, два обычных и два чистых ранее.
- Первый при 10% является нормальным и дает промежуточный итог 10%.
- Второе с 10% является чистым от предыдущего.Предыдущие вычеты суммируются до 10%, поэтому остаточная сумма составляет 90%.Таким образом, этот вычет должен составлять 9%, что дает промежуточный итог 19%
- Третий при 10% является нормальным и дает промежуточный итог 29%.
- Финал в 10% также за вычетом предыдущего.Предыдущие вычеты суммировались до 29%, поэтому оставшаяся сумма составляет 71%.Таким образом, этот вычет должен составлять 7,1%, что дает промежуточный итог 36,1%
После двух или трех дней попыток найти решение SQL для этого я немного разочарован тем, что не смоги надеюсь, что ничего не пропустил.
Итак, есть ли способ переписать это, не используя предложение модели и не написав функцию?