运行 包含借方贷方和上一行的总计 SQL Server 2012

Running Totals with debit credit and previous row SQL Server 2012

我在重新计算 运行 总数时遇到问题。

我有一种情况,我们有重复的交易,必须删除这些交易,并且必须根据金额重新计算初始和期末余额,并考虑到借方。

我的尝试是嵌套游标 (parent-child) 和 parent select 所有不同的 bookingNo 和 child 计算看起来很乱,我没用,没用 post 因为我不想混淆事情。

我知道在 SQL Server 2012 中您可以使用 (sum over partition by),但我不知道如何处理已删除的行等。

以下是我目前所做的

    --Create Table for testing
    IF object_id(N'TestTransaction', 'U') IS NOT NULL  DROP TABLE TestTransaction

    GO
    CREATE TABLE [TestTransaction]
    (
        [Id] [bigint] IDENTITY(1,1) NOT NULL,
        [BookingNo] [bigint] NOT NULL,
        [IsDebit] [bit] NOT NULL,
        [Amount] [decimal](18, 2) NOT NULL,
        [InitialBalance] [decimal](18, 2) NOT NULL,
        [ClosingBalance] [decimal](18, 2) NOT NULL
    ) ON [PRIMARY]
    GO

    INSERT [TestTransaction] ([BookingNo], [IsDebit], [Amount], [InitialBalance], [ClosingBalance]) 
    SELECT 200, 0, 100, 2000,2100 UNION ALL
    SELECT 200, 0, 100, 2100,2200 UNION ALL 
    SELECT 200, 1, 150, 2150,2000 UNION ALL 
    SELECT 200, 0, 300, 2000,2300 UNION ALL 
    SELECT 200, 0, 400, 2300,2700 UNION ALL 
    SELECT 200, 0, 250, 2700,2950 UNION ALL 
    SELECT 200, 0, 250, 2950,3200

--- end of setup

IF OBJECT_ID('tempdb..#tmpTransToDelete') IS NOT NULL DROP TABLE #tmpTransToDelete
GO
CREATE TABLE #tmpTransToDelete
(   BoookingNo bigint,
    Isdebit bit,
    amount decimal(18,2),
    InitialBalance decimal(18,2),
    ClosingBalance decimal(18,2)
)

DECLARE @RunnnigInitialBalance decimal(18,2),@RunnnigClosingBalance decimal(18,2)

INSERT #tmpTransToDelete(BoookingNo,Isdebit,amount,InitialBalance,ClosingBalance)
SELECT BookingNo,Isdebit,amount,InitialBalance,ClosingBalance
FROM TestTransaction 
WHERE ID IN (1,6)

--Delete all duplicate transaction (just to prove the point)
DELETE  TestTransaction WHERE ID IN (1,6)

-- now taking into account the deleted rows recalculate the lot and update the table.

有什么帮助吗?建议?

已编辑 结果应该是

    Id  BookingNo   IsDebit Amount  InitialBalance  ClosingBalance
    2   200         0       100.00  2000.00         2000.00
    3   200         1       150.00  2000.00         2150.00
    4   200         0       300.00  2150.00         2450.00
    5   200         0       400.00  2450.00         2850.00
    7   200         0       250.00  2600.00         2850.00

以下是使用您的数据得出的 运行 总数的示例:

SELECT BookingNo
    , Amount 
    , IsDebit
    , SUM(Amount * IIF(IsDebit = 0, 1, -1)) OVER (PARTITION BY BookingNo ORDER BY Id ROWS UNBOUNDED PRECEDING) AS RunningTotal

FROM TestTransaction

如果存在占初始余额的交易数据,我之前回复中的 RunningTotal 方法将起作用。但是,由于显然不是这种情况,我会说如果不将相对差异作为同一事务的一部分应用于所有后续行,就不能删除任何行。此外,我确信您的初始样本数据是错误的,这只会加剧混乱。在我看来应该是这样的:

SELECT 200, 0, 100, 2000,2100 UNION ALL
SELECT 200, 0, 100, 2100,2200 UNION ALL 
SELECT 200, 1, 150, 2200,2050 UNION ALL 
SELECT 200, 0, 300, 2050,2350 UNION ALL 
SELECT 200, 0, 400, 2350,2750 UNION ALL 
SELECT 200, 0, 250, 2750,3000 UNION ALL 
SELECT 200, 0, 250, 3000,3250

修正后,我将如何编写删除和更新事务:

BEGIN TRAN

DECLARE @tbd TABLE (
    Id bigint
    ,BookingNo bigint
    ,Amount decimal(18,2)
    );

DELETE FROM TestTransaction
OUTPUT deleted.Id
, deleted.BookingNo
, deleted.Amount * IIF(deleted.IsDebit = 0, 1, -1) AS Amount
INTO @tbd
WHERE ID IN (1,6);

WITH adj 
AS (
    SELECT tt.BookingNo, tt.Id, SUM(tbd.amount) AS Amount
    FROM TestTransaction tt 
    JOIN @tbd tbd ON tt.BookingNo = tbd.BookingNo AND tbd.id <= tt.id
    GROUP BY tt.BookingNo, tt.Id
    )

UPDATE tt
SET InitialBalance -= adj.Amount
    ,ClosingBalance -= adj.Amount
FROM TestTransaction tt
JOIN adj ON tt.BookingNo = adj.BookingNo AND tt.Id = adj.Id;

COMMIT TRAN

最终结果为:

Id  BookingNo   IsDebit Amount  InitialBalance  ClosingBalance
2   200 0   100.00  2000.00 2100.00
3   200 1   150.00  2100.00 1950.00
4   200 0   300.00  1950.00 2250.00
5   200 0   400.00  2250.00 2650.00
7   200 0   250.00  2650.00 2900.00