簡體   English   中英

遞歸SQL-如何獲得具有總計的表?

[英]Recursive SQL- How can I get this table with a running total?

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 + debit - credit )的前一行sum_debit 我輸入的每一行都是借方,但貸方數據為零,或者輸入貸方和借方的值為零。 我如何獲得sum_debit

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

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中測試

假設“ have”是您的數據表,則這應該是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

通常,解決方案是將行連接到該行之前的所有行,並提取這些行的總和,然后按所有內容分組以返回您期望的每一行。 例如這個問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM