sql - FIFO逻辑的实现
问题描述
在一个相当简单的数据库(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
.
解决方案
这可以使用 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 语法应该相同)
推荐阅读
- firebase - 在另一台服务器上通过 Firebase 功能进行身份验证的最佳做法是什么?
- python - 让 Alexa Skill 播放音频
- python - 相同的打印语句为排序算法(插入排序)提供不同的输出
- android-studio - 在什么情况下监听器参数是强制性的?
- flutter - 我们如何在颤动中绘制不同半径的饼图?
- python - 需要帮助创建计算器,无法导入 sympy
- python - Django框架上的分类广告网站
- java - Java中的reentrantlock如何保证内存可见性?
- c++ - C++在编译时获取函数地址并对其进行操作
- apache - 在 codeigniter 3.x 中使用 htpasswd 对特定 URL 进行密码保护