I have a set of date ranges consisting of both partially and fully overlapping dates, like this:
UserID StartDate EndDate ====== ========== ========== 1 2011-01-01 2011-01-02 <- A 1 2011-01-01 2011-01-10 <- A 1 2011-01-08 2011-02-15 <- A 1 2011-02-20 2011-03-10 <- B 2 2011-01-01 2011-01-20 <- C 2 2011-01-15 2011-01-25 <- C
Using T-SQL, I would like to create a new set of data, per user, with eliminated overlapping data, extending ranges and removing redundant data where needed, resulting in something like this:
UserID StartDate EndDate ====== ========== ========== 1 2011-01-01 2011-02-15 ('A', three rows combined, extending the range) 1 2011-02-20 2011-03-10 ('B', no change, no overlaps here) 2 2011-01-01 2011-01-25 ('C', two rows combined)
Cursors are fine if needed, but if I can do without them that would be even better.
Advertisement
Answer
For SQL Server 2005+
-- sample table with data declare @t table(UserID int, StartDate datetime, EndDate datetime) insert @t select 1, '20110101', '20110102' union all select 1, '20110101', '20110110' union all select 1, '20110108', '20110215' union all select 1, '20110220', '20110310' union all select 2, '20110101', '20110120' union all select 2, '20110115', '20110125' -- your query starts below select UserID, Min(NewStartDate) StartDate, MAX(enddate) EndDate from ( select *, NewStartDate = t.startdate+v.number, NewStartDateGroup = dateadd(d, 1- DENSE_RANK() over (partition by UserID order by t.startdate+v.number), t.startdate+v.number) from @t t inner join master..spt_values v on v.type='P' and v.number <= DATEDIFF(d, startdate, EndDate) ) X group by UserID, NewStartDateGroup order by UserID, StartDate
Notes:
- Replace
@t
with your table name