This query produces the result that you say that you're looking for. I'm using @t
in place of your original table1:
;With Ordered as (
select ROW_NUMBER() OVER (PARTITION BY Reference_VC
ORDER BY DateTime_DT) as rn,*
from @t
), Islands as (
select o.Reference_VC, o.rn as RnStart, o.rn as RnEnd,
o.DateTime_DT as dtStart, o.DateTime_DT as dtEnd
from Ordered o
left join
Ordered o_not
on o.Reference_VC = o_not.Reference_VC and
o.rn = o_not.rn + 1 and
o.DateTime_DT = DATEADD(second,1,o_not.DateTime_DT)
where
o_not.rn is null
union all
select
i.Reference_VC,i.RnStart,o.rn,i.dtStart,o.DateTime_DT
from Islands i
inner join
Ordered o
on
i.Reference_VC = o.Reference_VC and
i.RnEnd = o.rn - 1 and
i.dtEnd = DATEADD(second,-1,o.DateTime_DT)
), FinalIslands as (
select Reference_VC,RnStart,dtStart,
MAX(rnEnd) as rnEnd,MAX(dtEnd) as dtEnd,
ROW_NUMBER() OVER (Order BY Reference_VC,RnStart) as ID
from Islands i
group by Reference_VC,RnStart,dtStart
)
select
fi.ID,t.*
from
FinalIslands fi
inner join
@t t
on
fi.Reference_VC = t.Reference_VC and
fi.dtStart <= t.DateTime_DT and
fi.dtEnd >= t.DateTime_DT
The tricky part is the middle Common Table Expression (CTE), Islands
, which is recursive. The anchor portion (above UNION ALL
) finds rows which don't have a row immediately preceding them. The recursive part then tries to extend each one by finding a row which can be added onto the end.
This ends up producing rows which represent the full range of periods separated by 1 second - but it also includes all of the intermediate solutions generated by the recursive part. So the FinalIslands
CTE is used to remove the intermediate results and just take the full periods. I also took the opportunity, at this stage, of generating the ID
values.
We then take these periods and join back to the original table to produce the final output.
1 This is the sample data, in a table variable. You'd need to have this first and then the above query, in a single query window and without any GO
between them, to try it out:
declare @t table (Reference_VC varchar(5) not null,
DateTime_DT datetime not null,
Value_DEC decimal(10,9) not null)
insert into @t(Reference_VC,DateTime_DT,Value_DEC) values
('a.b.c','2000-07-29T00:43:30',0.2236),
('a.b.c','2000-07-29T00:43:31',0.2045),
('a.b.c','2000-07-29T00:43:35',0.2674),
('a.b.c','2000-07-29T00:43:36',0.2806),
('a.b.c','2000-07-29T00:43:40',0.3716),
('d.e.f','2000-07-29T00:42:35',0.2001),
('d.e.f','2000-07-29T00:42:36',0.2231),
('d.e.f','2000-07-29T00:42:37',0.2604),
('d.e.f','2000-07-29T00:42:38',0.3729),
('d.e.f','2000-07-29T00:42:39',0.2358),
('d.e.f','2000-07-29T00:42:45',0.2599),
('d.e.f','2000-07-29T00:42:46',0.2099),
('g.h.i','2000-07-29T01:13:42',0.3129),
('g.h.i','2000-07-29T01:13:42',0.2313),
('g.h.i','2000-07-29T01:13:42',0.2966),
('g.h.i','2000-07-29T01:13:42',0.3611),
('g.h.i','2000-07-29T01:13:42',0.2293),
('g.h.i','2000-07-29T01:13:42',0.3889)