SQL 中的 Fifo 方法
Fifo Method in SQL
我必须在 SQL 中实现类似于 FIFO 方法的东西。问题是我在不同的月份发行了积分,同时我在其他日期交换了积分。问题是我必须知道积分是多少个月前发行的,直到兑换为止。所以首先要兑换的积分是老年人,但如果 2014 年 6 月 30 日发放了 200 分,2014 年 7 月 31 日发放了 100 分,2014 年 8 月 31 日发放了 250 分。 200 点有 2 个月的开发(6 月的 200)和 50 点有 1 个月的开发(7 月发布的 100 中的 50)。我该如何编码?
我留下一些table以便更好地理解!
谢谢
Date of issue Number of account Issued points
30-abr 1 300
31-may 1 50
30-jun 1 100
30-jun 2 100
30-jun 3 120
31-may 4 20
30-jun 4 200
Date of exchange Number of account Exchanged points
30-jun 1 250
31-jul 1 200
31-jul 3 30
30-jun 4 30
31-jul 2 10
30-jun 3 30
31-ago 4 10
最后 table 我需要的是。
Issue date Months after issue Exchanged points
30-abr 2,00 250,00
30-abr 3,00 50,00
31-may 2,00 50,00
31-may 1,00 20,00
30-jun 1,00 100,00
30-jun 1,00 30,00
30-jun 0,00 10,00
30-jun 1,00 10,00
30-jun 0,00 30,00
30-jun 2,00 10,00
编辑:添加示例以阐明帐户 1 的问题:
3个不同月份发布的积分:
Date of issue Points
30-apr 300
31-may 50
30-jun 100
这些交换了 2 次:
Date of exchange Points
30-jun 250
31-jul 200
由于交换是从不同月份发放的积分进行的,结果应该是4个动作,所以最早的积分首先被使用:
Date of exchange Date of issue Points Months
30-jun 30-apr 250 2
31-jul 30-apr 50 3
31-jul 31-may 50 2
31-jul 30-jun 100 1
我试了一下这个 SQL returns 正确的结果。不知怎的,我觉得它可能有错误,但至少这是一个开始的地方(或者完全错误的方法):
;with I as (
select
date,
points,
account,
isnull((select sum(points) from issue i2
where i2.account = i1.account and i2.date < i1.date),0) as Cumulative
from
issue i1
),
E as (
select
date,
points,
account,
isnull((select sum(points) from Exchange e2
where e2.account = e1.account and e2.date < e1.date),0) as Cumulative
from
Exchange e1
),
X as (
select
I.Account,
I.Date as IDate, I.Points as IPoints, I.Cumulative as ICumulative,
E.Date as EDate, E.Points as EPoints, E.Cumulative as ECumulative
from I
join E on I.account = E.account
and I.Points + I.Cumulative > E.Cumulative
and E.Cumulative + E.Points > I.Cumulative
)
select
Account, IDate, datediff(month, IDate, EDate) as After,
case when EPoints + ECumulative < IPoints + ICumulative
then EPoints
else IPoints + ICumulative - ECumulative end
- case when ICumulative > ECumulative
then (ICumulative - ECumulative)
else 0 end as Points
from X
order by IDate, EDate
前 2 个 CTE(I 和 E)计算 运行 点总数,第 3 个 (X) 根据发布和交换的内容收集所需的行。计算最终 Points 列的公式只是反复试验,所以我不能 100% 确定它在所有情况下都是准确的:)
您可以在 SQL Fiddle
中尝试
我必须在 SQL 中实现类似于 FIFO 方法的东西。问题是我在不同的月份发行了积分,同时我在其他日期交换了积分。问题是我必须知道积分是多少个月前发行的,直到兑换为止。所以首先要兑换的积分是老年人,但如果 2014 年 6 月 30 日发放了 200 分,2014 年 7 月 31 日发放了 100 分,2014 年 8 月 31 日发放了 250 分。 200 点有 2 个月的开发(6 月的 200)和 50 点有 1 个月的开发(7 月发布的 100 中的 50)。我该如何编码?
我留下一些table以便更好地理解!
谢谢
Date of issue Number of account Issued points
30-abr 1 300
31-may 1 50
30-jun 1 100
30-jun 2 100
30-jun 3 120
31-may 4 20
30-jun 4 200
Date of exchange Number of account Exchanged points
30-jun 1 250
31-jul 1 200
31-jul 3 30
30-jun 4 30
31-jul 2 10
30-jun 3 30
31-ago 4 10
最后 table 我需要的是。
Issue date Months after issue Exchanged points
30-abr 2,00 250,00
30-abr 3,00 50,00
31-may 2,00 50,00
31-may 1,00 20,00
30-jun 1,00 100,00
30-jun 1,00 30,00
30-jun 0,00 10,00
30-jun 1,00 10,00
30-jun 0,00 30,00
30-jun 2,00 10,00
编辑:添加示例以阐明帐户 1 的问题:
3个不同月份发布的积分:
Date of issue Points
30-apr 300
31-may 50
30-jun 100
这些交换了 2 次:
Date of exchange Points
30-jun 250
31-jul 200
由于交换是从不同月份发放的积分进行的,结果应该是4个动作,所以最早的积分首先被使用:
Date of exchange Date of issue Points Months
30-jun 30-apr 250 2
31-jul 30-apr 50 3
31-jul 31-may 50 2
31-jul 30-jun 100 1
我试了一下这个 SQL returns 正确的结果。不知怎的,我觉得它可能有错误,但至少这是一个开始的地方(或者完全错误的方法):
;with I as (
select
date,
points,
account,
isnull((select sum(points) from issue i2
where i2.account = i1.account and i2.date < i1.date),0) as Cumulative
from
issue i1
),
E as (
select
date,
points,
account,
isnull((select sum(points) from Exchange e2
where e2.account = e1.account and e2.date < e1.date),0) as Cumulative
from
Exchange e1
),
X as (
select
I.Account,
I.Date as IDate, I.Points as IPoints, I.Cumulative as ICumulative,
E.Date as EDate, E.Points as EPoints, E.Cumulative as ECumulative
from I
join E on I.account = E.account
and I.Points + I.Cumulative > E.Cumulative
and E.Cumulative + E.Points > I.Cumulative
)
select
Account, IDate, datediff(month, IDate, EDate) as After,
case when EPoints + ECumulative < IPoints + ICumulative
then EPoints
else IPoints + ICumulative - ECumulative end
- case when ICumulative > ECumulative
then (ICumulative - ECumulative)
else 0 end as Points
from X
order by IDate, EDate
前 2 个 CTE(I 和 E)计算 运行 点总数,第 3 个 (X) 根据发布和交换的内容收集所需的行。计算最终 Points 列的公式只是反复试验,所以我不能 100% 确定它在所有情况下都是准确的:)
您可以在 SQL Fiddle
中尝试