我有以下数据(表1),我想在每个游戏日期结束时计算余额。但是,如果兑换日期小于游戏日期,则意味着需要从期末余额中减去该金额。我该如何写一条语句,查看特定行中的游戏日期,并查看所有先前行中的兑换日期,并获取其中赌博日期大于兑换日期的行的总和(表2) Table2
表1
DateRedeemed GamingDate Trip Amount
13/07/2017 03/07/2017 8001 100
17/07/2017 03/07/2017 8001 150
18/07/2017 04/07/2017 8001 125
27/07/2017 16/07/2017 8001 250
28/07/2017 16/07/2017 8001 310
27/07/2017 17/07/2017 8001 125
31/07/2017 18/07/2017 8001 75
28/07/2017 27/07/2017 8001 80
31/07/2017 28/07/2017 8001 100
表2
DateRedeemed GamingDate Trip Amount Running
13/07/2017 03/07/2017 8001 100 100
17/07/2017 03/07/2017 8001 150 250
18/07/2017 04/07/2017 8001 125 375
27/07/2017 16/07/2017 8001 250 525
28/07/2017 16/07/2017 8001 310 835
27/07/2017 17/07/2017 8001 125 810
31/07/2017 18/07/2017 8001 75 760
28/07/2017 27/07/2017 8001 80 590
31/07/2017 28/07/2017 8001 100 610
答案 0 :(得分:0)
使用解析函数代替标量子查询可能会有不同的解决方案,但是,我还没有弄清楚。同时,这里是此解决方案:
with t1 as (
select yd.*
, ROW_NUMBER() OVER (PARTITION BY trip ORDER BY GamingDate, DateRedeemed) rn
from YourData yd
)
select t1.*
, (select sum(amount) from t1 t2
where t2.trip = t1.trip
and t2.rn <= t1.rn
and t2.gamingdate <= t1.gamingdate
and t1.gamingdate < t2.dateredeemed) Running
from t1
order by trip, rn;
DateRedeemed | GamingDate | Trip | Amount | rn | Running :------------------ | :------------------ | ---: | -----: | :- | ------: 13/07/2017 00:00:00 | 03/07/2017 00:00:00 | 8001 | 100 | 1 | 100 17/07/2017 00:00:00 | 03/07/2017 00:00:00 | 8001 | 150 | 2 | 250 18/07/2017 00:00:00 | 04/07/2017 00:00:00 | 8001 | 125 | 3 | 375 27/07/2017 00:00:00 | 16/07/2017 00:00:00 | 8001 | 250 | 4 | 525 28/07/2017 00:00:00 | 16/07/2017 00:00:00 | 8001 | 310 | 5 | 835 27/07/2017 00:00:00 | 17/07/2017 00:00:00 | 8001 | 125 | 6 | 810 31/07/2017 00:00:00 | 18/07/2017 00:00:00 | 8001 | 75 | 7 | 760 28/07/2017 00:00:00 | 27/07/2017 00:00:00 | 8001 | 80 | 8 | 465 31/07/2017 00:00:00 | 28/07/2017 00:00:00 | 8001 | 100 | 9 | 175
我确实意识到最后两行与示例结果不匹配,但是,我认为这是由于示例结果中的错误而不是代码中的错误所致。如果您可以解释为什么这两个记录的示例结果正确,那么我可以尝试重新编写代码。
[编辑]
这是替代版本,它避免了效率低下的标量子查询,转而使用解析函数:
With Actions as (
select *, GamingDate ActionDate, 1 DBCR from Table1
union all
select *, DateRedeemed ActionDate, -1 DBCR from Table1
), Analytics as (
select *
, sum(Amount*DBCR) over (partition by trip
order by ActionDate, dbcr
, GamingDate, DateRedeemed) Running
from Actions
)
select DateRedeemed, GamingDate, Trip, Amount, Running
from Analytics
where dbcr = 1