Опростени типове.
DECLARE @t TABLE (AlarmId INT NOT NULL, State BIT NOT NULL, TIME SMALLDATETIME NOT NULL)
INSERT @t
VALUES
(1 ,0,'2011-11-15 09:00')
,(1 ,1,'2011-12-20 13:30')
,(2 ,1,'2011-11-17 15:01')
,(2 ,0,'2011-12-15 06:57')
,(3 ,0,'2011-11-10 11:42')
,(3 ,1,'2011-12-02 13:12')
,(3 ,0,'2011-12-24 14:41')
,(4 ,1,'2011-10-09 13:25')
,(4 ,0,'2012-01-07 08:29')
,(5 ,0,'2011-11-19 07:12')
,(5 ,1,'2011-11-28 15:48')
,(6 ,0,'2011-12-14 17:29')
,(6 ,1,'2011-12-23 23:46')
DECLARE @Start DATETIME = '20111201'
--Initial State DISABLED
;WITH Disabled(AlarmId, Time) AS
(
SELECT
AlarmId,
Time
FROM
(
SELECT
ROW_NUMBER() OVER (PARTITION BY AlarmId ORDER BY Time DESC) Ordinal,
AlarmId,
Time,
State
FROM @t
WHERE
Time < @Start
) t
WHERE
t.Ordinal = 1
AND t.STate = 0
UNION
SELECT
AlarmId,
TIME
FROM @t
WHERE
Time >= @start AND Time < DATEADD(m,1,@STart)
AND STate = 0
),
Enabled(AlarmId, Time) AS
(
SELECT
AlarmId,
TIME
FROM @t
WHERE
Time >= @start AND Time < DATEADD(m,1,@STart)
AND STate = 1
),
Alarms(AlarmId) AS
(
SELECT DISTINCT AlarmId FROM @t
)
SELECT
Alarms.AlarmId,
CASE WHEN Disabled.Time >= @start AND Disabled.Time < DATEADD(m,1,@STart) THEN Disabled.Time ELSE NULL END Disabled,
CASE WHEN Enabled.Time < Disabled.Time THEN NULL ELSE Enabled.Time END Enabled
FROM Alarms
LEFT JOIN Enabled
ON Alarms.AlarmId = Enabled.AlarmId
LEFT JOIN Disabled
ON Alarms.AlarmId = Disabled.AlarmId
WHERE COALESCE(Enabled.Time, Disabled.Time) IS NOT NULL