最初にLAGを使用することを検討していました。
しかしcummulative SUMを使用して、およびMINの窓のバージョンが2つ以上のDOWNのためにも動作します:
-- test reference data
declare @State table (id int, state varchar(4));
insert into @State (id, state) values
(2,'DOWN'),
(5,'UP')
-- test data, using a table variable
declare @AlertState table (alert_id int identity(1,1), host_id int, state_time datetime, state_id int);
insert into @AlertState (host_id, state_time, state_id) values
(119, GetDate()-0.32, 2),
(119, GetDate()-0.31, 5),
(119, GetDate()-0.24, 2),
(119, GetDate()-0.23, 2),
(119, GetDate()-0.22, 2),
(119, GetDate()-0.21, 5),
(119, GetDate()-0.15, 5),
(119, GetDate()-0.11, 2);
-- The query
select alert_id, host_id, state_time, state_id,
diff_min = (
case
when state_id = 5 then
datediff(minute, min(state_time) over (partition by host_id, stategroup), state_time)
when state_id = 2 and stategroup is null then
datediff(minute, state_time, cast(EOMONTH(GetDate()) as datetime)+1)
end),
s.state
from (
select alert_id, host_id, state_time, state_id,
sum(case state_id when 5 then 1 end) over (partition by host_id order by state_time desc) as stategroup
from @AlertState
where state_id in (2,5)
) q
left join @State s on s.id = q.state_id
order by state_time, alert_id;
使用しているSQL Serverのバージョンは? –