简体   繁体   中英

SQL Server - recursively calculated column

I need to calculate a column based of a seed row where each row's value uses the "previous" row's values. I feel like this should be a recursive query but I can't quite wrap my head around it.

To illustrate:

BOP     EOP     IN     OUT     Wk_Num
--------------------------------------
6       4       10     12      1
?       ?       2      6       2
?       ?       7      5       3
...     ...     ...    ...     ...

So the next row's BOP and EOP columns need to be calculated using the seed row. The IN and OUT values are already present in the table.

BOP = (previous row's EOP)

EOP = (Previous row's EOP) + IN - OUT [where IN and OUT are from the current row)

OUTPUT of this example should look like:

BOP     EOP     IN     OUT     Wk_num
-------------------------------------
6       4       10     12      1
4       0       2      6       2
0       2       7      5       3
2       6       4      0       4
...     ...     ...    ...     ...

You can use a Recursive CTE for this;

WITH RecursiveCTE AS (
  -- Base Case
  SELECT
    BOP,
    EOP,
    [IN],
    [OUT],
    [WK_Num]
  FROM [someTable]
  WHERE BOP IS NOT NULL

  UNION ALL

  SELECT
      r.EOP AS BOP,
      r.EOP + r2.[In] - r2.[Out] AS EOP,
      r2.[IN],
      r2.[OUT],
      r2.[WK_Num]
  FROM [someTable] r2
  INNER JOIN [RecursiveCTE] r
     ON r2.[Wk_Num] = r.[Wk_Num] + 1
)
SELECT * FROM RecursiveCTE

Here is a SQL Fiddle: http://sqlfiddle.com/#!18/e041f/1

You basically define the base case as the first row (by saying the row with BOP != null), then join to each following week with the Wk_Num + 1 join, and reference the previous rows values

You can use SUM OVER like this:

DECLARE @TempTable AS TABLE(T_In INT, T_Out INT, T_WeekNum INT)

INSERT INTO @TempTable VALUES (6, 0, 0)
INSERT INTO @TempTable VALUES (10, 12, 1)
INSERT INTO @TempTable VALUES (2, 6, 2)
INSERT INTO @TempTable VALUES (7, 5, 3)
INSERT INTO @TempTable VALUES (4, 0, 4)

SELECT
    SUM(T_In - T_Out) OVER(ORDER BY T_WeekNum ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) - T_In + T_Out AS T_Bop,
    SUM(T_In - T_Out) OVER(ORDER BY T_WeekNum ASC ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS T_Eop,
    T_In,
    T_Out,
    T_WeekNum
FROM @TempTable

The calculation is the same for BOP and EOP but the values from the current row are subtracted from the BOP column to get the value from the last row.

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