Ciao,
provo a farti un esempio.
presa questa tabella di esempio:
select 's'descr,convert(date,GETDATE())datalog into ##test where 1=0
insert ##test(descr,datalog)
values('S',GETDATE()+1),
('S',GETDATE()+2),
('I',GETDATE()+3),
('E',GETDATE()+4),
('I',GETDATE()+5),
('I',GETDATE()+6),
('S',GETDATE()+7),
('S',GETDATE()+8),
('I',GETDATE()+9),
('I',GETDATE()+10),
('E',GETDATE()+11),
('I',GETDATE()+12),
('S',GETDATE()+13),
('I',GETDATE()+14),
('I',GETDATE()+15),
('I',GETDATE()+16),
('E',GETDATE()+17),
('S',GETDATE()+18)
dove 'S'=start; 'I'=inattività; 'E'=end
la query potrebbe essere:
with tmp as
(
select ROW_NUMBER()over(order by datalog)r1,
*
from ##test
--order by datalog
)
(
select *
from
(
--estraggo le inattività strettamente vicine a uno start...
select --t1.r1,
max(t2.r1-t1.r1) d1,
max(t1.datalog)data1,
max(t1.descr)descr1,
max(t2.datalog)data2,
max(t2.descr)descr2,
min(t3.datalog)data3,
min(t3.descr)descr3
from (select * from tmp where descr='S') t1
join (select * from tmp where descr='I') t2
on t2.r1>t1.r1
join (select * from tmp where descr='E') t3
on t2.r1<t3.r1
where t2.r1-t1.r1=1
group by t2.r1-t1.r1,--t1.r1,
t2.datalog
)t1
--una volta trovate le inattività vicine uno start ricavo
-- tutte le altre che sono comprese tra la sua data e sua data
-- di termine
left join (select * from tmp where descr='I') t2
on t2.datalog>=t1.data2
and t2.datalog<t1.data3
)
order by d1--,d2--t1.datalog,t2.datalog,t3.datalog
non penso sia chiarissima la logica, x cui fammi pure delle domande che cerco di risponderti nel miglior modo possibile...