1
ID      debit   credit  sum_debit
---------------------------------
1       150     0       150
2       100     0       250
3       0       50      200
4       0       100     100
5       50      0       150

我有这张表,我的问题是如何获得sum_debit前一行的总和,sum_debit借方减去贷方(sum_debit = sum_debit + debit - credit)。我输入借方但贷方数据为零的每一新行,或者通过输入贷方和借方的值为零。我怎么得到sum_debit

4

2 回答 2

4

在 SQL-Server 2012 中,您可以使用新添加的ROWSorRANGE子句:

SELECT 
    ID, debit, credit,
    sum_debit = 
        SUM(debit - credit) 
        OVER (ORDER BY ID
              ROWS BETWEEN UNBOUNDED PRECEDING
                       AND CURRENT ROW
             )
FROM 
    CreditData
ORDER BY
    ID ;

SQL-Fiddle中测试

我们可以在OVER(ORDER BY ID)那里使用,结果是一样的。但是随后将使用默认值,即RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW存在效率差异(ROWS应该首选运行总计。)

@Aaron Bertrand有一篇很棒的文章,它对计算运行总计的各种方法进行了全面测试:运行总计的最佳方法——针对 SQL Server 2012 更新


对于以前版本的 SQL-Server,您必须使用其他方法,例如自连接、递归 CTE 或游标。这是一个光标解决方案,从 Aaron 的博客中盲目复制,表格和列已针对您的问题进行了调整:

DECLARE @cd TABLE
(   [ID] int PRIMARY KEY, 
    [debit] int, 
    [credit] int,
    [sum_debit] int
);

DECLARE
    @ID           INT,
    @debit        INT,
    @credit       INT,
    @RunningTotal INT = 0 ;

DECLARE c CURSOR
    LOCAL STATIC FORWARD_ONLY READ_ONLY
    FOR
    SELECT ID, debit, credit
      FROM CreditData
      ORDER BY ID ;

OPEN c ;

FETCH NEXT FROM c INTO @ID, @debit, @credit ;

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @RunningTotal = @RunningTotal + (@debit - @credit) ;

    INSERT @cd (ID, debit, credit, sum_debit )
        SELECT @ID, @debit, @credit, @RunningTotal ;

    FETCH NEXT FROM c INTO @ID, @debit, @credit ;
END

CLOSE c;
DEALLOCATE c;

SELECT ID, debit, credit, sum_debit
    FROM @cd
    ORDER BY ID ;

SQL-Fiddle-cursor中测试

于 2013-06-11T18:21:35.547 回答
2

假设“有”是您的数据表,这应该是一个 ANSI SQL 解决方案:

select h.*, sum(i.debit) as debsum, sum(i.credit) as credsum, sum(i.debit) - sum(i.credit) as rolling_sum
from have h inner join have i
on h.id >= i.id
group by h.id, h.debit, h.credit
order by h.id

通常,解决方案是将行连接到行之前的所有行,并提取这些行的总和,然后按所有内容分组以根据您的期望返回一行。比如这个问题

于 2013-06-11T18:21:28.980 回答