从运行总列

时间:2017-08-04 11:34:09

标签: sql sql-server tsql sql-server-2008-r2

我的SQL Server表中已经有一个正在运行的总列,如下所示

ID Value
1  1000
2  2000
3  3000
4  4000
5  5000

我需要得到值的增量总和(不确定它是否是正确的词),例如:1000 +(1000-2000)+(2000-3000)+(3000-4000)+(4000 -5000)= 5000

最终结果应该是这样的,这样我就可以得到INC_Sum列的总和

ID Value INC_Sum
1  1000   1000
2  2000   1000
3  3000   1000
4  4000   1000
5  5000   1000

我上面给出的那个是一个例子,我的表有数百万的更复杂的值。我正在运行SQL Server 2008 R2,有人可以帮我解决这个问题吗?

4 个答案:

答案 0 :(得分:1)

使用outer apply()根据id的顺序获取上一个值,使用isnull()替换0代替null值:

select 
    t.id
  , t.value
  , INC_Sum = t.value - isnull(x.previous_value,0)
from t
  outer apply (
    select top 1 
        previous_value = i.value
    from t as i
    where i.id < t.id
    order by i.id desc
    ) x

rextester演示:http://rextester.com/SYV5992

返回:

+----+-------+---------+
| id | value | INC_Sum |
+----+-------+---------+
|  1 |  1000 |    1000 |
|  2 |  2000 |    1000 |
|  3 |  3000 |    1000 |
|  4 |  4000 |    1000 |
|  5 |  5000 |    1000 |
+----+-------+---------+

答案 1 :(得分:0)

您可以使用lag()

select id, value,
       (value - lag(value, 1, 0) over (order by id)) as inc_sum
from t;

请注意,这使用了3参数形式的滞后。第二个参数是偏移量(要返回的行数)。第三个是默认值。

在SQL Server 2012之前,您将使用outer apply

select t.id, t.value,
       (t.value - coalesce(t2.value, 0) as inc_sum
from t outer apply
     (select top 1 t2.*
      from t t2
      where t2.id < t.id
      order by t2.id desc
     ) t2;

或者,如果您知道id中没有空白(这可能不是一个合理的假设:

select t.id, t.value,
       (t.value - coalesce(t2.value, 0) as inc_sum
from t left join
     t t2
     on t2.id = t.id - 1;

答案 2 :(得分:0)

我在此之前已经看过这个问题:

http://sqlfiddle.com/#!3/4e9e4

CREATE TABLE t
    ([id] int, [SomeNumt] int);

INSERT INTO t
    ([id], [SomeNumt])
VALUES
    (1, 10),
    (2, 12),
    (3, 3),
    (4, 15),
    (5, 23);

SELECT t1.id,
       t1.SomeNumt,
       SUM(t2.SomeNumt) AS SUM
FROM t t1
INNER JOIN t t2 ON t1.id >= t2.id
GROUP BY t1.id,
         t1.SomeNumt
ORDER BY t1.id

答案 3 :(得分:0)

SELECT t1.id,
   t1.SomeNum,
   t1.SomeNum - ISNULL(t2.SomeNum, 0) AS Delta
FROM t t1
LEFT OUTER JOIN t t2 ON t2.id = t1.id - 1
ORDER BY t1.id

或者,如果id列中存在空白:

SELECT t1.id,
   t1.SomeNum,
   t1.SomeNum - ISNULL(t2.SomeNum, 0) AS Delta
FROM t t1
LEFT OUTER JOIN t t2 ON t2.id = (SELECT MAX(t.id) FROM t WHERE t.id < t1.id)
ORDER BY t1.id

测试:

create table t(id int, somenum int)
insert into t select 1,1 
insert into t select 2,2 
insert into t select 3,3 
insert into t select 5,4