gpt4 book ai didi

sql - SQL中的库存平均成本计算

转载 作者:行者123 更新时间:2023-12-01 22:28:42 26 4
gpt4 key购买 nike

我想使用平均值计算库存成本,但我有点卡在这里...

考虑一个简单的交易表 tr :(ids 是自动递增的,负交易量表示卖出交易)

order_id | volume | price | type
1 | 1000 | 100 | B
2 | -500 | 110 | S
3 | 1500 | 80 | B
4 | -100 | 150 | S
5 | -600 | 110 | S
6 | 700 | 105 | B

现在我想知道每次交易后的总交易量和总成本。困难在于正确销售。在这一点上,卖出总是以平均成本计价(即卖出价格实际上与此处无关),因此交易订单在这里确实很重要。

理想情况下,结果如下所示:
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

现在,total_vol 很容易使用 sum(volume) over (...) ,另一方面总成本。我玩过窗口函数,但除非我遗漏了一些完全明显(或非常聪明)的东西,否则我认为它不能单独使用窗口函数来完成......

任何帮助,将不胜感激。 :)

更新:

这是我最终使用的代码,两个答案的组合(数据模型比我上面的简化示例稍微复杂一些,但您明白了):
select ser_num
, tr_id
, tr_date
, action_typ
, volume
, price
, total_vol
, trunc(total_costs,0) total_costs
, trunc(unit_costs,4) unit_costs
from itt
model
partition by (ser_num)
dimension by (row_number() over (partition by ser_num order by tr_date, tr_id) rn)
measures (tr_id, tr_date, volume, price, action_typ, 0 total_vol, 0 total_costs, 0 unit_costs)
rules automatic order
( total_vol[ANY] order by rn
= nvl(total_vol[cv()-1],0) +
decode(action_typ[cv()], 'Buy', 1, 'Sell', -1) * volume[cv()]
, total_costs[ANY] order by rn
= case action_typ[cv()]
when 'Buy' then volume[cv()] * price[cv()] + nvl(total_costs[cv()-1],0)
when 'Sell' then total_vol[cv()] * nvl(unit_costs[cv()-1],price[cv()])
end
, unit_costs[ANY] order by rn
= decode(total_vol[cv()], 0, unit_costs[cv()-1],
total_costs[cv()] / total_vol[cv()])
)
order by ser_num, tr_date, tr_id

一些观察:
  • 当使用分区和对前一个单元格的引用 ( cv()-1 ) 时,维度必须以与整个模型子句相同的方式进行分区(这也是使用迭代编号可能很棘手的原因)
  • 只要您在规则上指定正确的执行顺序,这里就不需要迭代(order by rn 编辑:Automatic order 自动执行此操作)
  • 这里可能不需要自动订购,但它不会受到伤害。
  • 最佳答案

    您可以使用 MODEL 子句来执行此递归计算

    创建示例表并插入数据

    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);

    查询( EDITED rules iterate(1000) 更改为 rules automatic order 实现了 MODEL 子句,因为它旨在发挥作用,即按顺序从上到下。它还使查询从 0.44 秒到 0.01 秒!)
    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

    输出
    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

    这个站点有一个关于 MODEL 子句的很好的教程
  • http://www.sqlsnippets.com/en/topic-11663.html

  • 上面数据的EXCEL表看起来像这样,公式向下延伸
        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

    关于sql - SQL中的库存平均成本计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5396827/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com