С учётом уточнения интерпретации данных, а также допуская что метки только последовательно добавляются, предлагаю использовать триггер на добавление. Создаёте таблицу периодов.
(Tag NVARCHAR(60), [StartTime] datetime, [EndTime] datetime)
В триггере: если метка более 2-х минут от предыдущей (определяется легко: последняя - 1), то добавляем строку и заносим в
StartTime
, если нет — то в
EndTime
.
Или процедура:
CREATE PROCEDURE DowntimeCalculatePeriod
AS
DECLARE @P TABLE ( ID INT IDENTITY,
[Tag] NVARCHAR(60), [StartTime] DATETIME, [EndTime] DATETIME)
DECLARE @DG1 NVARCHAR(60), @DT1 DATETIME
DECLARE @DG0 NVARCHAR(60) = CHAR(0x19), @DT0 DATETIME = '2020'
DECLARE @ID INT = -1
DECLARE DowntimeCalc CURSOR FOR
SELECT Tag, [DateTime] FROM Downtime ORDER BY 1, 2
OPEN DowntimeCalc
FETCH NEXT FROM DowntimeCalc INTO @DG1, @DT1
WHILE @@FETCH_STATUS = 0 BEGIN
IF ( @DG1 <> @DG0 ) OR (( @DG1 = @DG0 ) AND ( DATEDIFF( ss, @DT0, @DT1) > 90 )) BEGIN
INSERT INTO @P ([Tag], [StartTime]) VALUES ( @DG1, @DT1 )
SET @ID = SCOPE_IDENTITY()
END ELSE BEGIN
UPDATE @P SET [EndTime] = @DT1 WHERE ID = @ID
END
SET @DG0 = @DG1; SET @DT0 = @DT1
FETCH NEXT FROM DowntimeCalc INTO @DG1, @DT1
END
CLOSE DowntimeCalc
DEALLOCATE DowntimeCalc
SELECT [Tag], [StartTime], [EndTime] FROM @P
WHERE NOT [EndTime] IS NULL
ORDER BY 1, 2
GO
--
EXECUTE DowntimeCalculatePeriod