powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расчет значения после расчета)
20 сообщений из 20, страница 1 из 1
Расчет значения после расчета)
    #39486845
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select * from (
select 50 as pot, 100 as korr , 1 as div,1 as divp, to_date('01.01.2017', 'dd.mm.yyyy') as rep_date from dual
union 
select 0 as pot, 0 as korr ,2 as div,1 as divp, to_date('01.04.2017', 'dd.mm.yyyy') as rep_date from dual
union 
select 0 as pot, 0 as korr ,3 as div,1 as divp, to_date('01.07.2017', 'dd.mm.yyyy') as rep_date from dual
union 
select 0 as pot, 0 as korr ,4 as div,1 as divp, to_date('01.10.2017', 'dd.mm.yyyy') as rep_date from dual
union 
select 0 as pot, 0 as korr ,5 as div,1 as divp, to_date('01.01.2018', 'dd.mm.yyyy') as rep_date from dual
union 
select 0 as pot, 0 as korr ,6 as div,1 as divp, to_date('01.04.2018', 'dd.mm.yyyy') as rep_date from dual
) tab
order by rep_date



Необходимо, чтобы:
KORR = предыдущее значение lag(POT) + текущее DIV
POT = получившееся KORR + DIVP

POT KORR DIV DIVP REP_DATE50 100 1 1 01.01.201752+1 50+2 2 1 01.04.201756+1 53+3 3 1 01.07.201761+1 57+4 4 1 01.10.2017
что-то голова не бум бум, коллеги, есть предложения?
Спасибо!
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39486856
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нарастающий итог
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39486859
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

но пока не рассчитаю KORR я не смогу посчитать POT и так далее на каждый последующий период, если рассчитать нарастающий итог, то он сразу за все периоды будет считать по столбцу.
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39486902
Maxim Demenko
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mishanya3624,

?
Код: plsql
1.
first_value(pot - div - divp) over(order by rep_date) + sum(div + divp) over(order by rep_date)



Regards

Maxim
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39486916
Evgeny2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С логикой явно что-то ни так...
Мне кажется, постановку можно сделать более понятнее и прозрачнее.
Тут нужно знать предметную область данных и что нужно от них...
Но если данные нужно вывернуть так, то запрос делает как заказал.

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
with set1 as (select --+ materialize
                     pot,korr,div,divp,rep_date,
                     1+sign(min(rep_date) over (order by rep_date)-rep_date) as first_row   
                from (select 50 as pot, 100 as korr, 1 as div,1 as divp, to_date('01.01.2017', 'dd.mm.yyyy') as rep_date from dual
                       union 
                      select 0 as pot, 0 as korr ,2 as div,1 as divp, to_date('01.04.2017', 'dd.mm.yyyy') as rep_date from dual
                       union 
                      select 0 as pot, 0 as korr ,3 as div,1 as divp, to_date('01.07.2017', 'dd.mm.yyyy') as rep_date from dual
                       union 
                      select 0 as pot, 0 as korr ,4 as div,1 as divp, to_date('01.10.2017', 'dd.mm.yyyy') as rep_date from dual
                       union 
                      select 0 as pot, 0 as korr ,5 as div,1 as divp, to_date('01.01.2018', 'dd.mm.yyyy') as rep_date from dual
                       union 
                      select 0 as pot, 0 as korr ,6 as div,1 as divp, to_date('01.04.2018', 'dd.mm.yyyy') as rep_date from dual
                    ))
select pot,korr,div,divp,rep_date
  from set1
 where first_row = 1
 union all
select pot,korr,div,divp,rep_date 
  from (select pot,lag(pot,1,pot) over (order by rep_date)+div as korr,div,divp,rep_date,first_row 
          from (select pot,korr,div,divp,rep_date,first_row
                  from set1
                 where first_row = 1
                 union all
                select sum(new_pot) over (order by rep_date) as new_pot,korr,div,divp,rep_date,first_row
                  from (select pot,korr,div,divp,rep_date,first_row,
                               divp+lag(pot,1,0) over (order by rep_date)+div  as new_pot 
                          from set1)
                  where first_row = 0))
where first_row = 0
order by rep_date
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487084
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
скучно что-то...

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
select coalesce(pot_m,pot) pot, coalesce(korr_m,korr) korr, div, divp, rep_date
from tab
match_recognize(
measures strt.pot + sum(next.div) + sum(next.divp) as pot_m
       , strt.pot + sum(next.div) + sum(next.divp) - divp as korr_m
all rows per match
pattern(strt next+)
define next as next.rep_date > prev(rep_date)
)
order by rep_date
;

select *
from tab
model 
dimension by (row_number() over(order by rep_date) n)
measures(pot, korr, div, divp, rep_date)
rules sequential order
( pot[n>1] = pot[cv()-1]+div[cv()]+divp[cv()]
, korr[n>1] = pot[cv()]-divp[cv()]
)
order by rep_date
;

select *
from tab
model 
dimension by (row_number() over(order by rep_date) n)
measures(pot, korr, div, divp, rep_date)
rules automatic order
( korr[n>1] = pot[cv()-1]+div[cv()]
, pot[n>1] = korr[cv()]+divp[cv()]
)
order by rep_date
;


select
  case row_number()  over(order by rep_date) when 1 then pot else
    first_value(pot-div-divp) over(order by rep_date) + sum (div+divp) over (order by rep_date) end pot
, case row_number()  over(order by rep_date) when 1 then korr else
    first_value(pot-div-divp) over(order by rep_date) + sum (div+divp) over (order by rep_date)-divp end korr
, div, divp, rep_date
from tab
order by rep_date
;
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487109
Evgeny2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну так-то намного веселее...
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487406
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mishanya3624,

Можно так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
with t as (select * from ( 
select 50 as pot, 100 as korr , 1 as div,1 as divp, to_date('01.01.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,2 as div,1 as divp, to_date('01.04.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,3 as div,1 as divp, to_date('01.07.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,4 as div,1 as divp, to_date('01.10.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,5 as div,1 as divp, to_date('01.01.2018', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,6 as div,1 as divp, to_date('01.04.2018', 'dd.mm.yyyy') as rep_date from dual 
) tab 
order by rep_date) 
 
select
case rn when 1 then pot 
        else first_value(pot2) over (order by rep_date)+sum(div+divp) over (order by rep_date)
        end Pot, 
case rn when 1 then korr 
        else first_value(pot2) over (order by rep_date)+sum(div+divp) over (order by rep_date) - divp
        end korr 
from (select t.*, pot-(div+divp) pot2, row_number() over (order by rep_date) rn from t) k 
group by rep_date,korr,pot,pot2,rn,div,divp



Но как заметил Evgeny2 "С логикой явно что-то ни так... "
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487421
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Evgeny2,

Даже можно так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with t as (select * from ( 
select 50 as pot, 100 as korr , 1 as div,1 as divp, to_date('01.01.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,2 as div,1 as divp, to_date('01.04.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,3 as div,1 as divp, to_date('01.07.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,4 as div,1 as divp, to_date('01.10.2017', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,5 as div,1 as divp, to_date('01.01.2018', 'dd.mm.yyyy') as rep_date from dual 
union  
select 0 as pot, 0 as korr ,6 as div,1 as divp, to_date('01.04.2018', 'dd.mm.yyyy') as rep_date from dual 
) tab 
order by rep_date) 
 
select 
        first_value(pot2) over (order by rep_date)+sum(div+divp) over (order by rep_date)  Pot, 
        
case rn when 1 then korr 
        else first_value(pot2) over (order by rep_date)+sum(div+divp) over (order by rep_date) - divp
        end korr 
from (select t.*, pot-(div+divp) pot2, row_number() over (order by rep_date) rn from t) k 
group by rep_date,korr,pot2,rn,div,divp
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487527
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем огромное спасибо за помощь!
Но есть 1 недоговорка с моей стороны, посчитали мы KORR на 01,04,2017 он = 52, так вот есть условие, если получившийся KORR < DIVP в этом периоде, который например будет равен 70, а не 1, то POT = 0 и следующий расчет KORR уже будет брать POT = 0 , а не первоначальное 50... и тут я встал в тупик, так как нарастающий итог мне не дает желаемого результата (точнее я его не умею готовить)...
То есть сначала посчитали KORR сравнили его с DIVP , если KORR< DIVP , то POT в этом периоде = 0, иначе POT = KORR + DIVP
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487529
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получается как бы лестница, пока не узнаю результат KORR и не сравню его, не смогу посчитать POT на этот период, а следом нужно посчитать KORR след периода, который будет брать POT предудыщий...
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487536
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mishanya3624Получается как бы лестница, пока не узнаю результат KORR и не сравню его, не смогу посчитать POT на этот период, а следом нужно посчитать KORR след периода, который будет брать POT предудыщий...
Из моего предыдущего поста в этом топике можно взять варианты с моделькой и поиграться.
При наличии фантазии возможно также запилить искомое на recursive subquery clause factoring.
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487763
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrey_anonymous,

есть загвостка, если я делаю по 1 id, то все получается вот в такой схеме

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
model 

dimension by (row_number() over( order by  shareholder_name, report_date ) n)
measures(hhj,poten4a, korr4a,pred_id_4a,hg,kgr_ko_id,report_date,pred_id,name_ko,org_reg_num,hight_capital,shareholder_name,sum_div_paid,amount_sum_sh_cap,
cap_div_not_paid,hight_capital_sh,korr_divid,korr_capital,jh,sum_divid_for_korr,korr_id, sum_divid_for_korr4a,poten4 , kgr_id_4,report_date_4, shareholder_name_4)
rules automatic order
( korr4a[n>1] =poten4a[cv()-1] + sum_divid_for_korr4a[cv()],
poten4a[n>1] = case when korr4a[cv()] <= (hight_capital_sh[cv()] -cap_div_not_paid[cv()]) then 0 else korr4a[cv()] - (hight_capital_sh[cv()] -cap_div_not_paid[cv()])  end --+pot[cv()-1]+div[cv()]+divp[cv()]*/
 
)



но так как у меня shareholder_name много, то row_number() не подходит, так как он начинает расчет с 1 до последнего подряд, а надо по отдельным id делать отдельные расчеты с первого периода по последний...
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487764
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а на dense_rank() он ругается
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487767
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mishanya3624но так как у меня shareholder_name много, тоRTFM partition by
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487774
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,
также ругается

Код: plsql
1.
2.
3.
4.
5.
6.
ORA-32638: Non unique addressing in MODEL dimensions
32638. 00000 -  "Non unique addressing in MODEL dimensions"
*Cause:    The address space defined for the MODEL (partition by and dimension by
           expressions) do not uniquely identify each cell.
*Action:   Rewrite the MODEL clause. Using UNIQUE SINGLE REFERENCE
           option might help.



пробую по всякому крутить модель, никак...
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487781
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mishanya3624также ругаетсяРуки...
Ошибка в 17-ой строке.
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487785
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic,

? не понял... не, что с руками проблема, это понял:)
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487797
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
добавляю в модель
UNIQUE SINGLE REFERENCE
убираю все правила, все отрабатывает, как только добавляю любое правило, аля
Код: plsql
1.
korr4a[n>1] =poten4a[cv()]


то сразу ошибка
...
Рейтинг: 0 / 0
Расчет значения после расчета)
    #39487900
mishanya3624
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вроде разобрался, всем огромное спасибо!
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Расчет значения после расчета)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]