Here a working solution with an online version:
It simply loops over the records from start and works nearly identically like a human would do.
If it comes to a record where Col2 IN (1,3) (then @Inside = 1), it copies the value from Col1 to Col3 (and updates the @lastCol3).
In the other case it just copies the @LastCol3 into Col3.
-- INIT database
CREATE TABLE tbl1 (
Record_Number INT,
Col1 INT,
Col2 INT,
Col3expected INT,
Col3calculated INT
);
INSERT INTO tbl1(Record_Number, Col1, Col2, Col3expected)
VALUES
(1, 123, 1, 123),
(2, 456, 1, 456),
(3, 789, 2, 456),
(4, 147, 2, 456),
(5, 258, 3, 258),
(6, 852, 4, 258),
(7, 963, 2, 258),
(8, 213, 1, 213);
DECLARE @lastCol3 as int;
DECLARE @RecNumber as int;
DECLARE @Col1 as int;
DECLARE @Inside as int;
select @lastCol3 = null;
DECLARE tbl1_Cursor CURSOR FOR
select record_number, col1, case when col2 in (1,3) then 1 else 0 end
from tbl1
order by record_number;
OPEN tbl1_Cursor;
FETCH NEXT from tbl1_Cursor into @RecNumber, @Col1, @Inside;
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Inside = 1 -- means same as "Col2 IN (1, 3)"
BEGIN
update tbl1 set col3calculated = @Col1
where record_number = @RecNumber;
select @lastCol3 = @Col1;
END
ELSE
BEGIN
update tbl1 set col3calculated = @lastCol3
where record_number = @RecNumber;
END
FETCH NEXT from tbl1_Cursor into @RecNumber, @Col1, @Inside;
END;
CLOSE tbl1_Cursor;
DEALLOCATE tbl1_Cursor;
GO
SELECT *
FROM tbl1
WHERE col3expected = col3calculated
ORDER BY record_number
And the output:
| Record_Number |
Col1 |
Col2 |
Col3expected |
Col3calculated |
| 1 |
123 |
1 |
123 |
123 |
| 2 |
456 |
1 |
456 |
456 |
| 3 |
789 |
2 |
456 |
456 |
| 4 |
147 |
2 |
456 |
456 |
| 5 |
258 |
3 |
258 |
258 |
| 6 |
852 |
4 |
258 |
258 |
| 7 |
963 |
2 |
258 |
258 |
| 8 |
213 |
1 |
213 |
213 |
SELECT.