Inventory Average Cost Calculation in SQL

前端 未结 2 1646
别那么骄傲
别那么骄傲 2020-12-09 12:31

I want to compute inventory costs using average value, and I\'m somewhat stuck here...

Consider a simple transaction table tr: (ids are autoincrement, n

2条回答
  •  臣服心动
    2020-12-09 13:07

    You can use the MODEL clause to do this recursive calculation

    Create sample table and insert data

    create table costs (order_id int, volume int, price numeric(16,4), type char(1));
    
    insert into costs (order_id, volume, price) values (1,1000,100);
    insert into costs (order_id, volume, price) values (2,-500,110);
    insert into costs (order_id, volume, price) values (3,1500,80);
    insert into costs (order_id, volume, price) values (4,-100,150);
    insert into costs (order_id, volume, price) values (5,-600,110);
    insert into costs (order_id, volume, price) values (6,700,105);
    

    The query (EDITED changing rules iterate(1000) to rules automatic order implements the MODEL clause as it is intended to function, i.e. top to bottom sequentially. It also took the query from 0.44s to 0.01s!)

    select order_id, volume, price, total_vol, total_costs, unit_costs
        from (select order_id, volume, price,
                     volume total_vol,
                     0.0 total_costs,
                     0.0 unit_costs,
                     row_number() over (order by order_id) rn
              from costs order by order_id)
       model
             dimension by (order_id)
             measures (volume, price, total_vol, total_costs, unit_costs)
             rules automatic order -- iterate(1000)
             ( total_vol[any] = volume[cv()] + nvl(total_vol[cv()-1],0.0),
               total_costs[any] =
                        case SIGN(volume[cv()])
                        when -1 then total_vol[cv()] * nvl(unit_costs[cv()-1],0.0)
                        else volume[cv()] * price[cv()] + nvl(total_costs[cv()-1],0.0)
                        end,
               unit_costs[any] = total_costs[cv()] / total_vol[cv()]
             )
       order by order_id
    

    Output

    ORDER_ID VOLUME     PRICE      TOTAL_VOL   TOTAL_COSTS   UNIT_COSTS
    1        1000       100        1000        100000        100
    2        -500       110        500          50000        100
    3        1500        80        2000        170000        85
    4        -100       150        1900        161500        85
    5        -600       110        1300        110500        85
    6        700        105        2000        184000        92
    

    This site has a good tutorial on the MODEL clause

    • http://www.sqlsnippets.com/en/topic-11663.html


    The EXCEL sheet for the data above would look like this, with the formula extended downwards

        A         B       C      D          E                         F
     ---------------------------------------------------------------------------
    1|  order_id  volume  price  total_vol  total_costs               unit_costs
    2|                                   0                         0           0
    3|  1           1000    100  =C4+E3     =IF(C4<0,G3*E4,F3+C4*D4)  =F4/E4
    4|  2           -500    110  =C5+E4     =IF(C5<0,G4*E5,F4+C5*D5)  =F5/E5
    5|  3           1500     80  =C6+E5     =IF(C6<0,G5*E6,F5+C6*D6)  =F6/E6
    6|  4           -100    150  =C7+E6     =IF(C7<0,G6*E7,F6+C7*D7)  =F7/E7
    7|  5           -600    110  =C8+E7     =IF(C8<0,G7*E8,F7+C8*D8)  =F8/E8
    8|  6           700     105  =C9+E8     =IF(C9<0,G8*E9,F8+C9*D9)  =F9/E9
    

提交回复
热议问题