运行 包含借方贷方和上一行的总计 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
我在重新计算 运行 总数时遇到问题。
我有一种情况,我们有重复的交易,必须删除这些交易,并且必须根据金额重新计算初始和期末余额,并考虑到借方。
我的尝试是嵌套游标 (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