将一行与SQL中的所有先前行进行比较

时间:2019-01-14 17:27:06

标签: sql sql-server tsql

我有以下数据(表1),我想在每个游戏日期结束时计算余额。但是,如果兑换日期小于游戏日期,则意味着需要从期末余额中减去该金额。我该如何写一条语句,查看特定行中的游戏日期,并查看所有先前行中的兑换日期,并获取其中赌博日期大于兑换日期的行的总和(表2) Table2

Table1

表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

1 个答案:

答案 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