I have a table of data that looks a bit like this:
Name StartTime FinishTime Work
Bob 2010-08-03 08:00:00 2010-08-03 12:00:00 4
Bob 2010-08-03 13:00:00 2010-08-03 16:00:00 3
Pete 2010-08-04 08:00:00 2010-08-04 12:00:00 4
Mark 2010-08-04 10:00:00 2010-08-04 12:00:00 2
None of these date ranges should ever span over midnight.
I want to write SQL that will give me the following output, given an input Start Date of 2010-08-02 and a Finish Date of 2010-08-05
Date Name TotalWork
2010-08-03 Bob 7
2010-08-03 Pete 3
2010-08-04 Pete 4
2010-08-04 Mark 2
I could live with, and in fact may ultimately need, to have any days that do not have work associated also be represented in the results set, maybe as a row like this:
2010-08-05 NULL 0
I'm not quite sure how to iterate through dates in SQL in the same way that I would with other languages.
To give this some context, the output of this will ultimately plug into a Stacked Chart .Net control.
Could someone give me a clue, a link to a tutorial or some other help? Otherwise I think I'll be fiddling with this for days!
Thank you!
Jonathan
Try this:
Select DateAdd(day, 0, DateDiff(day, 0, StartDate)) Date,
Name, Sum (Work) TotalWork
From TableData
Group By Name, DateAdd(day, 0, DateDiff(day, 0, StartDate))
To get the missing days is harder.
Declare @SD DateTime, @ED DateTime -- StartDate and EndDate variables
Select @SD = DateAdd(day, 0, DateDiff(day, 0, Min(StartDate))),
@ED = DateAdd(day, 0, DateDiff(day, 0, Max(StartDate)))
From TableData
Declare @Ds Table (aDate SmallDateTime)
While @SD <= @ED Begin
Insert @Ds(aDate ) Values @SD
Set @SD = @SD + 1
End
-- ----------------------------------------------------
Select DateAdd(day, 0, DateDiff(day, 0, td.StartDate)) Date,
td.Name, Sum (td.Work) TotalWork
From @Ds ds Left Join TableData td
On DateAdd(day, 0, DateDiff(day, 0, tD.StartDate)) = ds.aDate
Group By Name, DateAdd(day, 0, DateDiff(day, 0, tD.StartDate))
EDIT, I am revisiting this with a solution that uses a Common Table Expression (CTE). This does NOT require use of a dates table.
Declare @SD DateTime, @ED DateTime
Declare @count integer = datediff(day, @SD, @ED)
With Ints(i) As
(Select 0 Union All
Select i + 1 From Ints
Where i < @count )
Select DateAdd(day, 0, DateDiff(day, 0, td.StartDate)) Date,
td.Name, Sum (td.Work) TotalWork
From Ints i
Left Join TableData d
On DateDiff(day, @SD, d.StartDate) = i.i
Group By d.Name, DateAdd(day, 0, DateDiff(day, 0, d.StartDate))