Примерно так:
DECLARE @DataSource TABLE
(
[machine_id] VARCHAR(6)
,[reason] VARCHAR(12)
,[start_time] TIME
);
INSERT INTO @DataSource([machine_id], [reason], [start_time])
VALUES ('001234', 'moving', '10:00:00')
,('001234', 'parked', '10:10:00')
,('001234', 'moving', '10:15:00')
,('001234', NULL, '10:20:00')
,('001234', NULL, '10:25:00')
,('001234', 'dumping', '10:30:00')
,('009876', 'parked', '10:00:00')
,('009876', NULL, '10:10:00')
,('009876', NULL, '10:15:00')
,('009876', 'moving', '10:20:00')
,('009876', 'dumping', '10:25:00');
SELECT [machine_id]
,[reason] AS [reason_old]
,ISNULL([reason], MAX([Reason]) OVER (PARTITION BY [machine_id], [RowID])) AS [reason]
,[start_time]
FROM
(
SELECT *
,SUM(IIF([reason] IS NULL, 0, 1)) OVER (PARTITION BY [machine_id] ORDER BY [start_time] ASC) AS [RowID]
FROM @DataSource
) DS
ORDER BY [machine_id]
,[start_time];
Идея состоит в том, чтобы использовать SUM
для группировки записей со значением NULL
со значением первая запись со значением NOT NULL
.
SELECT *
,SUM(IIF([reason] IS NULL, 0, 1)) OVER (PARTITION BY [machine_id] ORDER BY [start_time] ASC) AS [RowID]
FROM @DataSource;
Затем мы можем просто получить значение MAX/MIN
для такой группы, как эти агрегаты игнорировать NULL
с и вернет значение NOT NULL
.