Конференция "Базы" » разложить на составляющие сумму в SQL-запросе
 
  • Паша (26.12.12 11:42) [0]
    имеется произвольный набор чисел и некая сумма. ее надо разложить таким образом, чтобы каждый ее кусочек не превышал чисел из набора. звыняйте, немного сумбурно, вот пример

    сумма, скажем 11
    разложить так:

    числа   "расклад"
    5    5
    10    6
    20    0
    10    0



    я нарисовал свой вариант, но мне он не очень нравится, громоздко как-то


    with t as --набор чисел
       (select rownum n, t.*
         from
             (
              select 5 TVZ_BASE_AMOUNT from dual union all
              select 10  from dual union all
              select 20  from dual union all
              select 10  from dual
             ) t
       )
       ,          
       s as --раскладываемая сумма
       (select 11 sum_all from dual )

    select
          sum_all,
          TVZ_BASE_AMOUNT,

          case when sum_tvz < sum_all then TVZ_BASE_AMOUNT
               when sum_all- (sum_tvz- TVZ_BASE_AMOUNT) > 0 then sum_all- (sum_tvz- TVZ_BASE_AMOUNT)
               else 0
          end s --результат
    from
        (
         select
               sum_all,
               TVZ_BASE_AMOUNT,
               sum(TVZ_BASE_AMOUNT) over(order by n RANGE UNBOUNDED PRECEDING) sum_tvz
               
           from t,
                s
        )



    может можно иначе сделать, попроще?
  • Виталий Панасенко (26.12.12 11:49) [1]
    А СУБД указать?в ФБ можно в тригере/ХП такое решить. Я так понимаю, это партионный учет?
  • Паша (26.12.12 11:53) [2]
    блин, вроде указывал. Oracle
  • Паша (26.12.12 11:57) [3]
    да нет, это банковский учет, и надо не в триггере, а в запросе. отчет такой. в PL/SQL рисовать не хочу, там колонок - под сотню уже. маразм...
  • Кщд (26.12.12 14:57) [4]
    >Паша   (26.12.12 11:42)
    нормальненький у Вас вариант
    а вот через model(и - как следствие - один проход по таблице):

    with t as --набор чисел
      (select rownum n, t.*
        from
            (
             select 6 base, 25 sm from dual union all
             select 3, 25  from dual union all
             select 20, 25  from dual union all
             select 10, 25  from dual
            ) t
      )
    select *
    from t
    model
      return updated rows
      dimension by (n)
      measures (base, 0 as dist, sm)  
      rules (
            dist[any] = case
                          when least(base[cv()], sm[cv()] - nvl(sum(dist)[n < cv()], 0)) >= 0 then
                            least(base[cv()], sm[cv()] - nvl(sum(dist)[n < cv()], 0))
                          else
                            0
                          end
                         
            )

  • Паша (26.12.12 15:17) [5]
    о! сенк!
    вот чувствовал, что есть другой подход, более красивший.
    надо будет за model почитать, пока не встречалось
  • Кщд (26.12.12 15:32) [6]
    >Паша   (26.12.12 15:17) [5]
    он не более красивый, он - более другой)
  • Паша (26.12.12 16:05) [7]
    согласен. щаз читаю - злая штука!

    а есть в Оракле какая-нибудь такая штука...

    есть некий select, огромный. я бы хотел использовать его как базовый, но в разных вариациях. ну, добавить дополнительные таблички или поля, к примеру.
    вьюшка - не подходит, надо передавать параметры. курсор - подошло бы, но как его потом достать из селекта?

    пока что вижу только - копи/пасте. вот только сопровождать потом это удовольствие...
  • Кщд (26.12.12 16:27) [8]
    >Паша   (26.12.12 16:05) [7]
    во view таки можно использовать параметры
    например: select * from dual where 1 = ppackage.get_param_func;
  • Паша (26.12.12 16:40) [9]

    > Кщд   (26.12.12 16:27) [8]

    упс. таки да.
 
Конференция "Базы" » разложить на составляющие сумму в SQL-запросе
Есть новые Нет новых   [119660   +90][b:0][p:0.002]