MS SQL Server:用相同的列+计算滞后填充空表列?

时间:2018-06-28 19:18:15

标签: sql sql-server

我正在寻找一种在示例的C列中填充NULL值的方法:

ID Date     ColumnA ColumnB ColumnC
A  1/1/2018 0       0       NULL
A  2/1/2018 1       2       NULL
A  3/1/2018 1       2       NULL

具有ColumnC的滞后值,以便:

(ColumnB + Lag(ColumnC,1,0) over (PARTITION BY ID ORDER BY DATE) - ColumnA) AS ColumnC

ID Date     ColumnA ColumnB ColumnC
A  1/1/2018 0       0       0
A  2/1/2018 1       2       1
A  3/1/2018 1       2       2

不幸的是,lag()函数使我失败(我正在使用SQL Server)

谢谢!

编辑:添加了ID和日期列以显示所需的PARTITION和ORDER

3 个答案:

答案 0 :(得分:0)

我认为您需要递归查询才能获得所需的结果。 请注意:

ColumnC         = ColumnB + Lag(ColumnC,1,0) - ColumnA
--calculated                -- LAG refer to the same column

查询:

WITH cte AS (
  SELECT *, rn = ROW_NUMBER() OVER(ORDER BY 1/0)  
            -- quite dangerous, you need specific column
  FROM tab
), cte2 AS (
  SELECT rn, ColumnA, ColumnB, ColumnC=ColumnB-ColumnA
  FROM cte
  WHERE rn = 1
  UNION ALL
  SELECT t2.rn, t2.ColumnA, t2.ColumnB, t2.ColumnB-t2.ColumnA+t.ColumnC
  FROM cte2 t
  JOIN cte t2
    ON t.rn = t2.rn-1
)
SELECT *
FROM cte2;

DBFiddle Demo

答案 1 :(得分:0)

使用可更新的CTE。但是,您真正想要的是一个累加的总和:

with toupdate as (
      select t.*, sum(ColumnB - ColumnA) over (partition by id order by date) as new_columnC
      from t
     )
update toupdate
    set columnC = new_columnC;

我可以让您算出表明这就是您想要的数学。

请注意?。这是指定顺序的列。

答案 2 :(得分:0)

您可以这样做:

SELECT 
    ID
,   [Date]
,   ColumnA 
,   ColumnB
,   ColumnB + ISNULL(ColumnC,0) - ColumnA AS ColumnC
FROM (
SELECT 
    ID
,   [Date]
,   ColumnA 
,   ColumnB
,   LAG(ColumnB) OVER(PARTITION BY ID ORDER BY [Date]) AS ColumnC
FROM yourTable
WHERE 
    ColumnC IS NULL
) D

由于LAG()中的第一行始终为NULL,因此我们可以使用ISNULL()函数将其替换为0。请注意,我已指定ColumnC IS NULL以确保仅将结果应用于ColumnC上为NULL。