将前一行值减去当前行并按日期排序

时间:2019-01-20 10:21:30

标签: c# sql sql-server sql-server-2008

我表中的数据如下

SELECT ID, VALUE, acc_no, adate 
FROM TB_DailyStatement

   id    value   acc_no       adate
    ---------------------------------------------
    1     12     1      2019-01-01 07:40:38.250
    2     14     1      2019-01-02 07:41:05.883
    3     15     1      2019-01-13 07:41:22.377
    4     10     2      2019-01-14 08:15:53.403
    5     16     2      2019-01-03 13:52:47.347 
    6     19     1      2019-01-09 13:53:56.317
    7      7     3      2019-01-17 00:00:00.000
    8     24     2      2019-01-17 00:00:00.000
    9     19     2      2019-01-02 00:00:00.000
    10     7     1      2019-01-07 00:00:00.000
    11    24     1      2019-01-05 14:12:47.080
    12    20     3      2019-01-28 00:00:00.000

预期结果

    id     value   acc_no       aDATE                   result 
    ------------------------------------------------------------------------
    1     12     1        2019-01-01 07:40:38.250        12 (current row values of acc_no=1) 
    2     14     1        2019-01-02 07:41:05.883         2 (14 (current row values)-12(previous row value of acc_no=1))  
   11     24     1        2019-01-05 14:12:47.080        10 (24 (current row values)-14(previous date  value of acc_no=1))  
   10      7     1        2019-01-07 00:00:00.000       -17 (7 (current row values)-24(previous date  value of acc_no=1))  
    6     19     1        2019-01-09 13:53:56.317        12 (19 (current row values)-7(previous date  value of acc_no=1))  
    3     15     1        2019-01-13 07:41:22.377        -4 (15 (current row values)-19(previous date  value of acc_no=1))  
    9     19     2        2019-01-02 00:00:00.000        19 (12 (current row values of acc_no=2) 
    5     16     2        2019-01-03 13:52:47.347        -3 (16 (current row values)-14(previous date  value of acc_no=2))  
    4     10     2        2019-01-14 08:15:53.403        -6 (10 (current row values)-16(previous date  value of acc_no=2))  
    8     24     2        2019-01-17 00:00:00.000        14 (24 (current row values)-10(previous date  value of acc_no=2))  
    7      7     3        2019-01-17 00:00:00.000         7 (12(current row values of acc_no=3) 
   12     20     3        2019-01-28 00:00:00.000        13 (20 (current row values)-7(previous date  value of acc_no=3)) 

我尝试了以下查询

SELECT 
    id, t.value, acc_no, adate, 
    t.value - ISNULL(v.value, 0) AS result 
FROM 
    TB_DailyStatementt
OUTER APPLY 
    (SELECT TOP (1) value
     FROM TB_DailyStatement
     WHERE id < t.id
       AND acc_no = t.acc_no
     ORDER by id DESC) v

这将返回一些输出,但是我无法使用order by子句,即adate和acc_no

5 个答案:

答案 0 :(得分:0)

如果您想通过acc_no asc简单地得到此结果,就可以得到您期望的结果,

例如

从表顺序中按acc_no acs选择*

答案 1 :(得分:0)

SQL Server 2008中,您不能使用LEAD & LAG,为此,您可以像使用OUTER APPLY一样使用查询。

select * 
from  TB_DailyStatementt tout 
       outer apply (select top 1 value Prev 
                    from   TB_DailyStatementt t1 
                    where  t1.acc_no = tout.acc_no 
                           AND t1.adate < tout.adate 
                    order  by t1.adate desc)t1 
       outer apply (select top 1 value Next 
                    from   TB_DailyStatementt  t1 
                    where  t1.acc_no = tout.acc_no 
                           AND t1.adate > tout.adate 
                    order by t1.adate asc)t2 
       order by tout.adate,acc_no

这将为您提供所需的上一个和下一个值,具体取决于acc_no。现在,您可以应用开关大小写来设置字符串格式。

选中此Demo

答案 2 :(得分:0)

Collector<BigDecimal, ?, BigDecimal> collector 
    = Collectors.reducing(BigDecimal.ZERO, BigDecimal::add);

在原始查询中,您要加入ID,在所需结果中的注释表明您想使用订购日期,而不是ID。

因此,您可以通过将“ id

答案 3 :(得分:0)

我认为您的做法正确。您需要在外部查询中使用order by并修复表别名:

SELECT ds.id, ds.value, ds.acc_no, ds.adate, 
       (t.value - COALESCE(prev.value, 0)) AS result 
FROM TB_DailyStatementt ds OUTER APPLY 
    (SELECT TOP (1) ds2.value
     FROM TB_DailyStatement ds2
     WHERE ds2.id < ds.t.id AND ds2.acc_no = ds.acc_no
     ORDER by ds2.id DESC
    ) prev
ORDER BY ds.acc_no, ds.adate

答案 4 :(得分:0)

尝试一下:

    Select  *, CASE WHEN LAG(value) OVER(partition by acc_no order by adate) IS NULL THEN value
    ELSE value - LAG(value) OVER(partition by acc_no order by adate) END  result from TB_DailyStatement