简体   繁体   中英

SQL Server - Add or Subtract from Previous Value

I'm trying to get the balance from this data

Date           Logged      Closed
-------------- ----------- -----------
1-Jan-2016     0           0
2-Jan-2016     8           7
3-Jan-2016     8           8
4-Jan-2016     25          11
5-Jan-2016     20          16
6-Jan-2016     14          13
7-Jan-2016     10          12
8-Jan-2016     9           7
9-Jan-2016     12          12
10-Jan-2016    3           4

The expected output is

Date           Logged      Closed      Balance
-------------- ----------- ----------- ----------
1-Jan-2016     0           0           0
2-Jan-2016     8           7           1 
3-Jan-2016     8           8           1
4-Jan-2016     25          11          15
5-Jan-2016     20          16          19
6-Jan-2016     14          13          20
7-Jan-2016     10          12          18
8-Jan-2016     9           7           20
9-Jan-2016     12          12          20
10-Jan-2016    3           4           27

The formula is BALANCE = PREVIOUSBALANCE + LOGGED - CLOSED.

Example formula :

Jan 5 Balance (15) = 1(prevBalance) + 25(currentLogged) - 11(currentClosed)

I've tried this formula but does not get anywhere close to the desired result.

WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (ORDER BY Date),
Date, Logged, Closed
FROM Table
)

SELECT
(prev.Logged - prev.Closed)+ (a.Logged-a.Closed) as [Balance]
FROM CTE

LEFT JOIN CTE prev ON prev.rownum = CTE.rownum - 1

Other references used

SQL Server - Calculate current row value using previous row value

http://blog.sqlauthority.com/2013/09/22/sql-server-how-to-access-the-previous-row-and-next-row-value-in-select-statement/

You can do this using Window function sum .

Try this:

select 
    t.*,
    sum(logged - closed) over (order by date) balance
from your_table t;

The problem of your answer is the Balanced of the previous row is not available when you calculate (SQL-Server 's All-at-once principle). Your question has a hidden requirement of calculating sum of all the previous rows, ordered by date.

Try this (only applied for SQL Server 2012 and beyond)

SELECT
    [Date], Logged, Closed,
    SUM(Logged) OVER (ORDER BY [Date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
    - SUM (Closed) OVER (ORDER BY [Date] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Balance
FROM
    <<Table>>

For previous version:

SELECT
    t.[Date], t.Logged, t.Closed, sub.L - sub.C AS Balanced
FROM
    <<Table>> t
    CROSS APPLY ( SELECT SUM(Logged) AS L, SUM(Closed) AS c FROM <<Table>> WHERE [Date] <= t.[Date]) AS sub

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM