繁体   English   中英

将前一行值减去当前行

[英]Subtract previous row value to current row

我有下表:

id  value  acc_no 
-----------------
1     12     1 
2     14     1 
3     15     1 
4     10     2 
5     16     2 
6     19     1 
7      7     3 
8     24     2 

预期产量

id  value  acc_no   result 
------------------------------
1     12     1          12(current row values of acc_no=1) 
2     14     1          2(14 (current row values)-12(previous row value of acc_no=1))  
3     15     1          1(15-14) 
4     10     2          10(current row values of acc_no=2) 
5     16     2          6(16 (current row values)-12(previous row value of acc_no=2)) 
6     19     1          4(19(current row values)-15(previous row value of acc_no=1)) 
7     7      3           7(current row values of acc_no=3) 
8     24     2          8(24(current row values)-16(previous row value of acc_no=2)) 

我试过这个查询:

select 
    id, value,
    acc_no,
    (value - (select value from tb_acc t1 where t1.id = t.id - 1)) as result 
from 
    tb_acc t

但是我没有得到预期的正确输出

DECLARE @Test TABLE (
    id      int,
    value   int,
    acc_no  int
) 
INSERT @Test(id, value, acc_no)
VALUES
(1, 12, 1),
(2, 14, 1), 
(3, 15, 1),
(4, 10, 2),
(5, 16, 2),
(6, 19, 1),
(7,  7, 3),
(8, 24, 2)

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

使用窗口功能:

;WITH CTE AS 
(
   SELECT id, value, acc_no, 
          ROW_NUMBER() OVER (PARTITION BY acc_no ORDER BY id) AS seq
   FROM tb_acc
)
SELECT t1.*, t1.value - COALESCE(t2.value, 0)
FROM CTE AS t1
LEFT JOIN CTE AS t2 ON t1.acc_no = t2.acc_no AND t1.seq = t2.seq + 1

你可以喜欢

选项一:使用LAG()函数(我只是注意到您正在使用2008,但我也将其发布给其他读者)

SELECT *,
       Value - LAG(Value, 1, 0) OVER(PARTITION BY acc_no ORDER BY ID) Result
FROM T
ORDER BY ID;

选项二:使用CTE和窗口函数+ ISNULL()

WITH CTE AS
(
  SELECT *,
         ROW_NUMBER() OVER(PARTITION BY acc_no ORDER BY id) RN
  FROM T
)
SELECT T1.id,
       T1.value,
       T1.acc_no,
       T1.value - ISNULL(T2.value, 0) Result
FROM CTE T1 LEFT JOIN CTE T2
     ON T1.acc_no = T2.acc_no
        AND 
        T1.RN = T2.RN + 1
ORDER BY T1.id;

现场演示

您只需要一个窗口总和:

SELECT 
    id  
    ,value  
    ,acc_no
    ,value - isnull(sum([value])  over (partition by acc_no order by id rows between 1 preceding and 1 preceding ), 0) as result
FROM tb_acc t
order by id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM