'SQL update value from previous row dynamically
I'm trying to update a value to equal the previous row's value within that PrimaryID group - but the previous row could also be updated based on my query. I can do it with a loop or cursor but for the few-million rows I'm dealing with, it just takes too long. I've used the CTE with LAG function described below but it's static and won't take into account values I've already updated.
declare @table table (PrimaryID int, SecondaryID int, Val decimal(10,2))
insert into @table values
(1,1,100),
(1,2,150),
(1,3,null),
(2,1,50),
(2,2,null),
(2,3,null),
(2,4,60),
(2,5,null),
(2,6,null)
;WITH cte AS
(
SELECT PrimaryID, SecondaryID, LAG(Val, 1) OVER (PARTITION BY PrimaryID ORDER BY SecondaryID) previousVal FROM @table
)
UPDATE t
SET Val = cte.previousVal
FROM @table t
JOIN cte ON t.PrimaryID = cte.PrimaryID AND t.SecondaryID = cte.SecondaryID
WHERE t.SecondaryID > 1
AND t.Val IS NULL
select * from @table
initial data
| PrimaryID | SecondaryID | Value |
|---|---|---|
| 1 | 1 | 100 |
| 1 | 2 | NULL |
| 1 | 3 | NULL |
| 2 | 1 | 50 |
| 2 | 2 | NULL |
| 2 | 3 | NULL |
| 2 | 4 | 60 |
| 2 | 5 | NULL |
| 2 | 6 | NULL |
expected outcome
| Primary ID | Secondary ID | Value |
|---|---|---|
| 1 | 1 | 100 |
| 1 | 2 | 100 |
| 1 | 3 | 100 |
| 2 | 1 | 50 |
| 2 | 2 | 50 |
| 2 | 3 | 50 |
| 2 | 4 | 60 |
| 2 | 5 | 60 |
| 2 | 6 | 60 |
actual outcome
| PrimaryID | SecondaryID | Value |
|---|---|---|
| 1 | 1 | 100 |
| 1 | 2 | 100 |
| 1 | 3 | NULL |
| 2 | 1 | 50 |
| 2 | 2 | 50 |
| 2 | 3 | NULL |
| 2 | 4 | 60 |
| 2 | 5 | 60 |
| 2 | 6 | NULL |
Solution 1:[1]
use APPLY operator to find the last not null value to update back the table
UPDATE t
SET Val = v.Val
FROM @table t
CROSS APPLY
(
SELECT TOP 1 x.Val
FROM @table x
WHERE x.PrimaryID = t.PrimaryID
AND x.SecondaryID < t.SecondaryID
AND x.Val IS NOT NULL
ORDER BY x.SecondaryID DESC
) v
WHERE t.Val IS NULL
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Squirrel |
