Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

T-SQL iterative calculation without loop

I have below financial data, I need to show balance as on date.
I have used below logic using loop, but I want to achieve same thing without loop or cursor, using single query. Any idea on this will be helpful.

 DROP TABLE IF EXISTS #Transact;
    CREATE TABLE #Transact
    (
        dt DATE,
        Transact VARCHAR(1),
        Amount INT,
        Balance INT
    )
    
    INSERT INTO #Transact
    (
        dt,
        Transact,
        Amount
    )
    SELECT *
    FROM
    (
        VALUES
            ('01-01-2022', 'C', 1000),
            ('02-01-2022', 'C', 1000),
            ('03-01-2022', 'D', 1000),
            ('04-01-2022', 'C', 2000),
            ('05-01-2022', 'C', 2000),
            ('06-01-2022', 'D', 2000),
            ('07-01-2022', 'D', 2000),
            ('08-01-2022', 'C', 3000),
            ('09-01-2022', 'C', 1500),
            ('10-01-2022', 'D', 1500),
            ('11-01-2022', 'D', 1500),
            ('12-01-2022', 'C', 1500)
    ) VTE (DT, Transact, Amount);
    
    declare @interval date = '01-01-2022',
            @balance int
    
    WHILE (@interval <= (select max(dt) FROM #Transact))
    BEGIN
        ;WITH CTE
         AS (SELECT *,
                    LAG(Balance) Over (Order by dt) AS PreBalance
             FROM #Transact
            )
        UPDATE CTE
        SET Balance = CASE
                          WHEN Transact = 'C' THEN
                              Amount + ISNULL(PreBalance, 0)
                          ELSE
                              ISNULL(PreBalance, 0) - Amount
                      END
        WHERE dt = @interval
    
        SET @interval = DATEADD(DAY, 1, @interval)
        SELECT @balance = Balance
        from #Transact
        where dt = @interval
    END
    
    SELECT * FROM #Transact;

I have very large amount of such data, and my requirement is to avoid cursor or loop for this calculation.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

I think it’s a running total, so you need a windowed SUM() and a CASE expression:

SELECT 
   dt, Transact, Amount, 
   SUM(
      CASE 
         WHEN Transact = 'C' THEN Amount 
         WHEN Transact = 'D' THEN -Amount
         ELSE 0
      END) OVER (ORDER BY dt) AS Balance
FROM #Transact   
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading