powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите довести до ума нарастающий итог
6 сообщений из 6, страница 1 из 1
Помогите довести до ума нарастающий итог
    #40050696
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне нужно составить матрицу тарифов и посчитать по определенной формуле их стоимость.
У тарифа есть стартовая стоимость, на которую применяется скидка за период и клубная скидка.
Кроме того у тарифа есть увеличение скорости, которое имеет фиксированную скорость и к которой скидка не применяется (просто прибавляется определенная стоимость к предыдущей скорости).
Тарифы и формулы я свел в такую таблицу:
Код: 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.
47.
48.
with TL as
(
  select 0 as POS, '' as NAME, 0 as FEE, 0 as BEG from dual where 0=1
  union all select 1, 'Начальный', 800, null from dual
  union all select 2, 'Популярный', 1000, null from dual
  union all select 3, 'Премиальный', 1200, 300 from dual
  union all select 4, 'Премиум+', 1400, 1000 from dual
)
, TP as
(
  select 1 as PERIOD, null as DISCOUNT from dual
  union all select 3, 5 from dual
  union all select 6, 10 from dual
  union all select 12, 15 from dual
)
, RR as
(
  select 100 as RATE from dual
  union all select 200 from dual
  union all select 300 from dual
  union all select 1000 from dual
)
, RS as
(
  select 100 as STEP, null as RATE, null as LINE from dual
  union all select 200, 100, 'Начальный' from dual
)
, SS as
(
  select null as NAME, null as DISCOUNT from dual
  union all select 'Клуб', 10 from dual
)
select SS.NAME as STATUS
, TL.NAME as LINE
, TP.PERIOD
, RR.RATE
, dense_rank() over(partition by TL.NAME, TP.PERIOD order by RR.RATE) as RANK
, nvl(RSO.STEP, RS.STEP) as STEP
, case
    when RR.RATE = 100 then TL.FEE * (1-nvl(TP.DISCOUNT,0)/100) * TP.PERIOD * (1-nvl(SS.DISCOUNT,0)/100)
  end as FEE
from TL
join TP on (TP.PERIOD > 0)
join RR on (RR.RATE = 100 or RR.RATE >= nvl(TL.BEG,0))
join RS on (RS.RATE is null and RS.LINE is null)
left join RS RSO on (RSO.RATE = RR.RATE and RSO.LINE = TL.NAME)
join SS on (1=1)
order by SS.NAME nulls first, TL.POS, TP.PERIOD, RR.RATE


В столбе FEE указана стартовая стоимость. Мне нужно туда же добавить нарастающий итог, группа начинается с RANK=1, прибавляется значение STEP.
Не хочется добавлять еще один подзапрос, поверх которого будет добавлена sum() over().
Можно ли просуммировать столбец на том же уровне?
По идее нужно использовать lag, но не пойму как применять эту функцию на самой себе.
...
Рейтинг: 0 / 0
Помогите довести до ума нарастающий итог
    #40050702
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чудак, ты уже давно должен понять, что твоё вербальное некачественное формулирование задачи, за которую тебе (заметь, не нам!) платят зряплату, можно компенсировать хотя бы желаемым результатом.
...
Рейтинг: 0 / 0
Помогите довести до ума нарастающий итог
    #40050711
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Результат у меня получается такой:
STATUSLINEPERIODRATERANKSTEPFEEНачальный11001200800Начальный12002100Начальный13003100Начальный110004100Начальный310012002280Начальный32002100Начальный33003100Начальный310004100Начальный610012004320Начальный62002100Начальный63003100Начальный610004100

А я хотел бы такой:
STATUSLINEPERIODRATERANKSTEPFEEНачальный11001200800Начальный120021001000Начальный130031001100Начальный1100041001200Начальный310012002280Начальный320021002880Начальный330031003180Начальный3100041003480Начальный610012004320Начальный620021005520Начальный630031006120Начальный6100041006720

То есть заполнить пропущенные суммы нарастающим итогом.

В качестве "костыля" я сделал так:
Код: plsql
1.
2.
3.
4.
, case
    when RR.RATE = 100 then TL.FEE * (1-nvl(TP.DISCOUNT,0)/100) * TP.PERIOD * (1-nvl(SS.DISCOUNT,0)/100)
    else TL.FEE * (1-nvl(TP.DISCOUNT,0)/100) * TP.PERIOD * (1-nvl(SS.DISCOUNT,0)/100) + TP.PERIOD * (case when TL.NAME = 'Начальный' then 100 else 0 end + 100 * (dense_rank() over(partition by SS.NAME, TL.NAME, TP.PERIOD order by RR.RATE) - 1))
  end as FEE


но хотелось бы обойтись формулами.
...
Рейтинг: 0 / 0
Помогите довести до ума нарастающий итог
    #40050809
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.


То есть заполнить пропущенные суммы нарастающим итогом.



last_value ignore nulls заполнит пропущенные + sum() over наростающий

.....
stax
...
Рейтинг: 0 / 0
Помогите довести до ума нарастающий итог
    #40050812
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
del
...
Рейтинг: 0 / 0
Помогите довести до ума нарастающий итог
    #40051029
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо.
Но все же сделал по другому, обернул в подзапрос и посчитал нарастающим итогом.
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Помогите довести до ума нарастающий итог
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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