【问题标题】:Implementation of FIFO logicFIFO逻辑的实现
【发布时间】:2018-12-26 19:00:02
【问题描述】:

在一个相当简单的数据库(Firebird 3.0)中,我有一个包含与产品相关字段的库存表:

购买

QTY     PRICE   VALUE    Date
10      10      100      1.12.2018
25      9       225      5.12.2018
30      8       240      12.12.2018
50      7       350      14.12.2018
100     6       600      22.12.2018

总计(数量、价格、价值):215、40、1515

这里,SOLD QTY 是 150,我需要对“PURCHASE”中最早的记录求和(值),直到 sum(QTY) = SOLD QTY

【问题讨论】:

  • 您的预期输出到底是什么?此外,如果总和不正好为 150,会发生什么情况(鉴于您提供的值不是这种情况,您可以求和为 115 或 215)。
  • 请阅读SQL tag info 中关于如何发布一个好的SQL 问题的说明和edit 相应的问题。
  • 嗨,马克,谢谢。
  • @edlink 我觉得你的方法是错误的。我觉得你试图实现某种追赶处理。然后你真的必须做一个专门的 FIFO 查询,而不是通过扫描整个所有购买历史并总结从创建日到今天的所有行来模拟它。我相信,它会在几年内滚雪球,让你的程序进入 DailyWTF。阅读我与 Helena 的讨论,看看我的担忧和想法是否也适用于您的案例。 stackoverflow.com/questions/53750647
  • 我同意@Arioch'The ,你真的想存储交易发生时发生的事情。前任。 “我们以每台 15 美元的价格售出 15 台。成本是 10 台 9 美元,5 台 10 美元” 至少,存储当时的平均或扩展成本。我已经在生产 ERP 中看到过这种方式。 [希望这是你可以控制的。]

标签: sql firebird


【解决方案1】:

这可以使用 Firebird 3 支持的 Windowed Aggregates 轻松解决:

select *
  ,case when cumulative_qty <= sold_qty then qty
        when sold_qty-(cumulative_qty - qty) < 0 then 0
        else sold_qty-(cumulative_qty - qty)
   end as qty_sold
  ,case when cumulative_qty <= sold_qty then qty
        when sold_qty-(cumulative_qty - qty) < 0 then 0
        else sold_qty-(cumulative_qty - qty)
   end * price as value_sold
from
 (
   select *
     ,150 as sold_qty
      -- cumulative sum of quantity in stock (FIFO)
     ,sum(qty) over (order by date rows unbounded preceding) as cumulative_qty
   from tab
 ) as dt
;

现在你可以计算总和了:

select 
  sum(case when cumulative_qty <= sold_qty then qty
           when sold_qty-(cumulative_qty - qty) < 0 then 0
           else sold_qty-(cumulative_qty - qty)
      end) as qty_sold
  ,sum(case when cumulative_qty <= sold_qty then qty
            when sold_qty-(cumulative_qty - qty) < 0 then 0
            else sold_qty-(cumulative_qty - qty)
       end * price) as value_sold
from
 (
   select *
     ,150 as sold_qty
      -- cumulative sum of quantity in stock (FIFO)
     ,sum(qty) over (order by date rows unbounded preceding) as cumulative_qty
   from tab
 ) as dt
;

参见db<>fiddle(使用 Postgres,但 Firebird 语法应该相同)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多