2015-07-21 30 views
0

我在重新計算運行總計時遇到了問題。使用借記貸方和前一行運行總計SQL Server 2012

我有一個重複交易的情況,必須刪除這些交易,並且必須根據金額重新計算初始和期末餘額,並考慮何時存款。

我的嘗試是有嵌套遊標(父子)和父母選擇所有不同的預訂號和孩子計算看起來非常混亂,我沒有工作,沒有發佈,因爲我沒有想混淆東西。

我知道在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 

回答

0

在我以前的響應中的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 
+0

Jason APOLOGIES !!!你是正確的樣本數據是錯誤的,我剛剛意識到這一點,因爲我正在努力解決這個問題。我消化你的解決方案並回到你身邊。無論如何,非常感謝你的回覆時間 – developer9969

+0

有什麼可說的。我仍然不相信沒有遊標,這很好。 – developer9969

+0

我可以問你一件事。你認爲你的查詢可以修改爲重新調整Id,例如1-2-3-4等。而不是2-4-等等。明顯地比將它移除爲標識柱並且更加像LineNo。謝謝。我能想到的唯一方法是回到一個光標,並且您的解決方案非常簡潔。感謝 – developer9969

0

這裏是一個正在運行的總使用你的數據的一個例子:

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 
+0

嗨,謝謝你的時間,試圖理解你做了什麼我編輯了我應該期待的結果,那些不符合你的。看看我編輯的問題 – developer9969