5

Being primarily a C# developer, I'm scratching my head when trying to create a pure T-SQL based solution to a problem involving summarizing days/month given a set of date ranges.

I have a set of data looking something like this:

UserID  Department  StartDate   EndDate
======  ==========  ==========  ==========
1       A           2011-01-02  2011-01-05
1       A           2011-01-20  2011-01-25
1       A           2011-02-25  2011-03-05
1       B           2011-01-21  2011-01-22
2       A           2011-01-01  2011-01-20
3       C           2011-01-01  2011-02-03

The date ranges are non-overlapping, may span several months, there may exist several ranges for a specific user and department within a single month. What I would like to do is to summarize the number of days (inclusive) per user, department, year and month, like this (with reservations for any math errors in my example...):

UserID  Department  Year  Month  Days
======  ==========  ====  =====  ====
1       A           2011  01     10
1       A           2011  02     4
1       A           2011  03     5
1       B           2011  01     2
2       A           2011  01     20
3       C           2011  01     31
3       C           2011  02     3

This data is going into a new table used by reporting tools. I hope the problem description is clear enough, this is my first posting here, be gentle :-)

Thanks in advance!

Jakob Möllås
  • 4,239
  • 3
  • 33
  • 61

1 Answers1

8

Working sample

-- sample data in a temp table
declare @t table (UserID int, Department char(1), StartDate datetime, EndDate datetime)
insert @t select
1 ,'A', '2011-01-02','2011-01-05'union all select
1 ,'A', '2011-01-20','2011-01-25'union all select
1 ,'A', '2011-02-25','2011-03-05'union all select
1 ,'B', '2011-01-21','2011-01-22'union all select
2 ,'A', '2011-01-01','2011-01-20'union all select
3 ,'C', '2011-01-01','2011-02-03'

-- the query you need is below this line    

select UserID, Department,
    YEAR(StartDate+v.number) Year,
    MONTH(StartDate+v.number) Month, COUNT(*) Days
from @t t
inner join master..spt_values v
  on v.type='P' and v.number <= DATEDIFF(d, startdate, enddate)
group by UserID, Department, YEAR(StartDate+v.number), MONTH(StartDate+v.number)
order by UserID, Department, Year, Month
RichardTheKiwi
  • 105,798
  • 26
  • 196
  • 262
  • Thanks! Works fine, interesting use of **master..spt_values**, have not encountered that system table before. More info on **master..spt_values** can be found [here](http://stackoverflow.com/questions/4273723/what-is-the-purpose-of-system-table-table-master-spt-values-and-what-are-the-mea). – Jakob Möllås Mar 06 '11 at 21:44