powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Условный нарастающий итог
25 сообщений из 26, страница 1 из 2
Условный нарастающий итог
    #39760789
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Похоже, я настолько тупой, что потратил более двух часов на следующую задачу безрезультатно:

Допустим, есть две колонки:
ORDVALa1b2b1c3d0d2d5e100f50f50
Нужно получить выборку (дебильным) нарастающим итогом значения VAL c группировкой/сортировкой по ORD,
при условии, что .. (будет проще показать) :

Результат (сортировка по ORD):
ORDVALкомментарийa1началоb4b:2+1=3; + предыдущая_строка = 4c4c:3 меньше чем 4 поэтому не учитывается=0; + предыдущая_строка = 4d11d:0+2+5=7; + предыдущая_строка = 11e111e:100; + предыдущая_строка = 111f111f:50+50=100 меньше чем 111 поэтому не учитывается=0; + предыдущая_строка = 111
фу, вроде бы не ошибся нигде

Нужно без использования PL/SQL. Сломал себе об это голову. Может быть кто поможет? Пожалуйста
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760799
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--ORDddd
фу, вроде бы не ошибся нигдеУверен?
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760844
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

Если по быстрому (на коленках собрать) то вот:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',	 2 from dual union all
select 'b',	1 from dual union all
select 'c',	3 from dual union all
select 'd',	0 from dual union all
select 'd',	2 from dual union all
select 'd',	5 from dual union all
select 'e',	100 from dual union all
select 'f',	50 from dual union all
select 'f',	50 from dual )

select Ord, sum(Rate*S_Val) over (order by Ord) Result
From ( select Ord, 
              case when Sum(sum(val)) over (order by Ord)-sum(val) > sum(val) then 0 else 1 end Кate, 
              sum(val) S_Val
         from t 
        group by Ord)
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760852
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Хотя нет, там не учитываеться отнимаемый ранее параметр ... сейчас чтот придумаю
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760853
Dshedoo
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXLMaximaXXL,

Хотя нет, там не учитываеться отнимаемый ранее параметр ... сейчас чтот придумаю

Только with рекурсия.
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760861
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

a,c,e не повторяются?

ps
непонятно что не получается, та в лоб и закодировать

.....
stax
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760870
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
--Eugene--,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',	 2 from dual union all
select 'b',	1 from dual union all
select 'c',	3 from dual union all
select 'd',	0 from dual union all
select 'd',	2 from dual union all
select 'd',	5 from dual union all
select 'e',	100 from dual union all
select 'f',	50 from dual union all
select 'f',	50 from dual )
select
    ord
   ,sum(sum(val))over(order by ord) running_total
from t 
group by ord;
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760872
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
ааа, не дочитал условие
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760875
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',	 2 from dual union all
select 'b',	1 from dual union all
select 'c',	3 from dual union all
select 'd',	0 from dual union all
select 'd',	2 from dual union all
select 'd',	5 from dual union all
select 'e',	100 from dual union all
select 'f',	50 from dual union all
select 'f',	50 from dual )
,v as (
select
    ord
   ,sum(val) sv
   ,sum(sum(val))over(order by ord) running_total
from t 
group by ord
)
select
   ord, sv, running_total, running_total - sum(case when sv<= running_total-sv then sv else 0 end)over(order by ord) as fixed_running_total
from v;
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760878
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Elic--Eugene--ORDddd
фу, вроде бы не ошибся нигдеУверен?есть сомнения?Staxa,c,e не повторяются?

ps
непонятно что не получается, та в лоб и закодироватьпро повторение вопрос не вполне понятен, а закодировать в PL/SQL(?) - нужно запросом
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760880
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

влоб
Код: 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.
  1  with t(ORD,VAL) as (
  2  select 'a',        1 from dual union all
  3  select 'b',        2 from dual union all
  4  select 'b',        1 from dual union all
  5  select 'c',        3 from dual union all
  6  select 'd',        0 from dual union all
  7  select 'd',        2 from dual union all
  8  select 'd',        5 from dual union all
  9  select 'e',        100 from dual union all
 10  select 'f',        50 from dual union all
 11  select 'f',        50 from dual )
 12  , tt as (
 13  select
 14    row_number() over (order by ord) rn
 15   ,ord
 16   ,sum(val) sv
 17  from t group by ord)
 18  , ttt (rn,ord,sv,ss) as (
 19  select rn,ord,sv,1 from tt where rn=1
 20  UNION all
 21  select tt.rn,tt.ord,tt.sv,
 22  case when tt.ord in ('b','d','e') then tt.sv+ttt.ss
 23       when tt.ord in ('c','f') then decode(sign(tt.sv-ttt.ss),-1,0,tt.sv)+ttt.ss
 24       else 0 end
 25  from tt,ttt where tt.rn=ttt.rn+1
 26  )
 27* select ord,ss from ttt order by 1
SQL> /

O         SS
- ----------
a          1
b          4
c          4
d         11
e        111
f        111

6 rows selected.



зи
мож моделькой или мач-рекогнизе получтся

....
stax
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760883
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

мож вместо abcdf четные/нечетные брать, алгоритм обсчета вроде как бы чередуется

,,,,,
stax
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760890
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
После группировки
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
select ord1, val, valsum
from t
match_recognize(
    order by ord
    measures
      ord as ord1, 
      sum(sums.val) as valsum
    all rows per match
    pattern ((sums|dummy)+)
    define 
      sums as sums.val >= sum(sums.val)-sums.val
) tt;

O        VAL     VALSUM
- ---------- ----------
a          1          1
b          3          4
c          3          4
d          7         11
e        100        111
f        100        111
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760891
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',	 2 from dual union all
select 'b',	1 from dual union all
select 'c',	3 from dual union all
select 'd',	0 from dual union all
select 'd',	2 from dual union all
select 'd',	5 from dual union all
select 'e',	100 from dual union all
select 'f',	50 from dual union all
select 'f',	50 from dual )
,v as (
select
    ord
   ,sum(val) sv
   ,sum(sum(val))over(order by ord) running_total
from t 
group by ord
)
select
   ord, sv, running_total, running_total - sum(case when sv<= running_total-sv then sv else 0 end)over(order by ord) as fixed_running_total
from v;

неее. на строке d FIXED_RUNNING_TOTAL должно быть 11, а не 4

Stax
Код: 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.
  1  with t(ORD,VAL) as (
  2  select 'a',        1 from dual union all
  3  select 'b',        2 from dual union all
  4  select 'b',        1 from dual union all
  5  select 'c',        3 from dual union all
  6  select 'd',        0 from dual union all
  7  select 'd',        2 from dual union all
  8  select 'd',        5 from dual union all
  9  select 'e',        100 from dual union all
 10  select 'f',        50 from dual union all
 11  select 'f',        50 from dual )
 12  , tt as (
 13  select
 14    row_number() over (order by ord) rn
 15   ,ord
 16   ,sum(val) sv
 17  from t group by ord)
 18  , ttt (rn,ord,sv,ss) as (
 19  select rn,ord,sv,1 from tt where rn=1
 20  UNION all
 21  select tt.rn,tt.ord,tt.sv,
 22  case when tt.ord in ('b','d','e') then tt.sv+ttt.ss
 23       when tt.ord in ('c','f') then decode(sign(tt.sv-ttt.ss),-1,0,tt.sv)+ttt.ss
 24       else 0 end
 25  from tt,ttt where tt.rn=ttt.rn+1
 26  )
 27* select ord,ss from ttt order by 1

ну как-то уж совсем влоб ))))
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760894
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
--Eugene--неее. на строке d FIXED_RUNNING_TOTAL должно быть 11, а не 4ну подумай немножко-то... в запросе всего один символ лишний...
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760930
Фотография --Eugene--
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

и то верно
спасибо!
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760945
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

у этого решения косяк такой-же как и у моего:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',	 2 from dual union all
select 'b',	1 from dual union all
select 'c',	3 from dual union all
select 'd',	0 from dual union all
select 'd',	2 from dual union all
select 'd',	4 from dual union all
select 'e',	100 from dual union all
select 'f',	50 from dual union all
select 'f',	50 from dual )
,v as (
select
    ord
   ,sum(val) sv
   ,sum(sum(val))over(order by ord) running_total
from t 
group by ord
)
select
   ord, sv, running_total, running_total - sum(case when sv< running_total-sv then sv else 0 end)over(order by ord) as fixed_running_total
from v;


если поставить например у 'd' =4 то он не будет учитывать накопленные минуса и даст неправильный результат:
ORD SV RUNNING_TOTAL FIXED_RUNNING_TOTALa 1 1 1b 3 4 4c 3 7 4d 6 13 4e 100 113 104f 100 213 104

Тут реально надо через with делать или match_recognize
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39760994
Фотография Sayan Malakshinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
MaximaXXLесли поставить например у 'd' =4 то он не будет учитывать накопленные минуса и даст неправильный результат:
ORD SV RUNNING_TOTAL FIXED_RUNNING_TOTALa 1 1 1b 3 4 4c 3 7* 4d 6* 13 4e 100 113 104f 100 213 104

Тут реально надо через with делать или match_recognizeВ смысле? 6 меньше 7, поэтому этот результат не засчитывается. Все ок
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761009
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--Eugene--,

мож я неправильно условие понял
"поэтому не учитывается=0" для всех строк или токо для cf?

ps
если для всех, то убрать case

....
stax
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761022
Фотография SY
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MaximaXXL,

Код: 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.
49.
50.
with t as (
select 'a' ORD, 1 VAL from dual union all 
select 'b',  2 from dual union all
select 'b', 1 from dual union all
select 'c', 3 from dual union all
select 'd', 0 from dual union all
select 'd', 2 from dual union all
select 'd', 4 from dual union all
select 'e', 100 from dual union all
select 'f', 50 from dual union all
select 'f', 50 from dual ),
 v as (
           select  row_number() over(order by ord) rn,
                   ord,
                   sum(val) val
             from  t
             group by ord
          ),
r(rn,ord,val) as (
                   select  *
                     from  v
                     where rn = 1
                  union all
                   select  v.rn,
                           v.ord,
                           case
                             when v.val < r.val then r.val
                             else v.val + r.val
                           end val
                     from  r,
                           v
                     where v.rn = r.rn + 1
                 )
select  ord,
        val
  from  r
/

O        VAL
- ----------
a          1
b          4
c          4
d         10
e        110
f        110

6 rows selected.

SQL> 



SY.
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761024
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtender,

Как Я понял, 6 не должно проверяться с 7, а должно провериться со значением предыдуще расчитанного столбца (FIXED_RUNNING_TOTAL) = 4 и как следствие должно быть учтено. Хотя постановка двоякая и пример не отображает этого поведения
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761027
MaximaXXL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY,

Как делать через with я понимаю, я попытался сделать без него (пример не совсем удачен и данные сошлись) и понял что поможет только явная рекурсия. Но автор топика не я и подходит ему with подход или нет мне сложно судить.
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761035
Фотография andrey_anonymous
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xtenderMaximaXXLесли поставить например у 'd' =4 то он не будет учитывать накопленные минуса и даст неправильный результат:
ORD SV RUNNING_TOTAL FIXED_RUNNING_TOTAL...b 3 4 4c 3 7* 4d 6* 13 4...
Тут реально надо через with делать или match_recognizeВ смысле? 6 меньше 7
...но больше 4
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761037
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SY
Код: plsql
1.
2.
3.
4.
                           case
                             when v.val < r.val then r.val
                             else v.val + r.val
                           end val


SY.

decode(sign(tt.sv-ttt.ss),-1,0,tt.sv)+ttt.ss
....
stax
...
Рейтинг: 0 / 0
Условный нарастающий итог
    #39761140
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
with function pip(c sys_refcursor) return sys.ku$_errorlines as
   g  varchar2(100);
   v  number;
   vs number;
   r  sys.ku$_errorlines;
begin
   r  := sys.ku$_errorlines();
   vs := 0; -- -
   loop
      fetch c into g, v;
      exit when c%notfound;
      if v > vs then
        vs := vs + v;
      end if;
      r.extend();
      r(r.count) := sys.ku$_errorline(vs, g);
   end loop;
   return r;
end;
t(ord, val) as ( ... )
select errortext ord, errornumber val
from pip(cursor(select ord, sum(val) from t group by ord order by ord));

ORD        VAL
--- ----------
a            1
b            4
c            4
d           11
e          111
f          111
...
Рейтинг: 0 / 0
25 сообщений из 26, страница 1 из 2
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Условный нарастающий итог
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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