2015-07-21 6 views
0

У меня возникают проблемы с пересчетом текущих итогов.Выполнение итогов с дебетовым кредитом и предыдущей строкой SQL Server 2012

У меня есть ситуация, когда у нас есть повторяющиеся транзакции, и они должны быть удалены, а начальный и конечный баланс должны быть пересчитаны на основе суммы и с учетом того, когда isdebit.

Моя попытка состоит в том, чтобы иметь вложенные курсоры (родительский-родительский), а родительский элемент выбирает все отдельное бронированиеНо, а ребенок делает расчет очень грязным, и я не работал, не публиковал его, потому что не сделал хотят запутать вещи.

Я знаю, что в 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

Джейсон извинения !!! вы правы, данные образца были неправильными, я только что осознал это сам, так как я работаю над этим решением. Позвольте мне переварить ваше решение и вернуться к you.anyway огромное спасибо за ваше время в ответе – developer9969

+0

Что можно сказать.THANKS! я все еще не верю никаким курсорам. Это хорошо. – developer9969

+0

Могу ли я спросить вас одну вещь. Как вы думаете, ваш запрос может быть изменен, чтобы повторить идентификацию, например, 1-2-3-4 и т. Д., А не 2-4 и т. Д. Obviosly, чем удалить его как идентификационный код и быть более как LineNo. Благодарю. Единственный способ, о котором я могу думать, - вернуться к курсору, и ваше решение намного опрятно. Thanks – 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

Привет спасибо за ваше время, пытаясь понять, что вы сделали я редактировал результаты, которые я должен ожидать и те DonT матча yours.have взглянуть на моем отредактированной вопрос – developer9969