Author |
Topic |
st99015207
Starting Member
2 Posts |
Posted - 2009-09-08 : 13:34:26
|
Hi all,We have an application that uses a standard 24 hours period for a reporting 'day', but the day doesnt run from midnight to midnight, it actually runs from 5AM to 5AM. Its easy to return aggregate totals grouped by the day using datepart for a standard mignight to midnight day, but how would I acheive the same grouping using my strange 5AM-> 5AM period??The table in question has a column for the date and a seperate column for the time.Example data from table:Date Time Value---------------------------------------01/01/2009 15:00:00 23.4001/01/2009 21:00:00 40.5001/01/2009 02:00:00 60.0002/01/2009 05:10:00 30.4503/01/2009 01:12:00 30.0005/01/2009 15:00:00 24.60Desired Output:Date Total----------------------01/01/2009 123.9002/01/2009 60.4505/01/2009 24.60I hope this makes sense?!I already have the where clause for returning rows that fall between two dates/times....Therefore its simply the grouping logic I am struggling with...Many thanks in adavance.Nick |
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2009-09-08 : 14:10:39
|
Shouldn't this be 12/31/2008 per your specs? '01/01/2009 02:00:00' , and what happened to '03/01/2009 01:12:00 30.00'?JimEveryday I learn something that somebody else already knew |
|
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2009-09-08 : 14:35:06
|
I agree with jim's first observation. Here is one way which basically relies on a seperate table with from/to dates to JOIN on. There are various ways to accomplish that but this way uses a recursive cte.set dateformat 'dmy'declare @t table (dt datetime, v money)insert @tselect '01/01/2009 15:00:00', 23.40 union allselect '01/01/2009 21:00:00', 40.50 union allselect '01/01/2009 02:00:00', 60.00 union allselect '02/01/2009 05:10:00', 30.45 union allselect '03/01/2009 01:12:00', 30.00 union allselect '05/01/2009 15:00:00', 24.60declare @last datetime; select @last = max(dt) from @t;with dts (grp, dt_fm, dt_to)as( select 1 ,dateadd(day, datediff(day, 1, min(dt)), '1900-01-01 05:00:00.000') ,dateadd(day, datediff(day, 0, min(dt)), '1900-01-01 05:00:00.000') from @t union all select dts.grp + 1 ,dateadd(day, 1, dts.dt_fm) ,dateadd(day, 1, dts.dt_to) from dts where dateadd(day, 1, dts.dt_fm) < @last)select min(dt_fm), sum(v)from @t tjoin dts d on d.dt_fm < t.dt and d.dt_to >= t.dtgroup by d.grphaving sum(v) > 0OUTPUT:----------------------- ---------------------2008-12-31 05:00:00.000 60.002009-01-01 05:00:00.000 63.902009-01-02 05:00:00.000 60.452009-01-05 05:00:00.000 24.60 Be One with the OptimizerTG |
|
|
Michael Valentine Jones
Yak DBA Kernel (pronounced Colonel)
7020 Posts |
Posted - 2009-09-08 : 15:01:40
|
set dateformat 'dmy'declare @MyTable table (MyDate datetime, Amt money)insert @MyTableselect '01/01/2009 15:00:00', 23.40 union allselect '01/01/2009 21:00:00', 40.50 union allselect '01/01/2009 02:00:00', 60.00 union allselect '02/01/2009 05:10:00', 30.45 union allselect '03/01/2009 01:12:00', 30.00 union allselect '05/01/2009 15:00:00', 24.60select BusinessDate = dateadd(dd,datediff(dd,0,dateadd(hh,-5,a.MyDate)),0), Amt = sum(Amt)from @MyTable agroup by dateadd(dd,datediff(dd,0,dateadd(hh,-5,a.MyDate)),0)order by dateadd(dd,datediff(dd,0,dateadd(hh,-5,a.MyDate)),0) Results:BusinessDate Amt------------------------------------------------------ --------2008-12-31 00:00:00.000 60.00002009-01-01 00:00:00.000 63.90002009-01-02 00:00:00.000 60.45002009-01-05 00:00:00.000 24.6000 CODO ERGO SUM |
|
|
jimf
Master Smack Fu Yak Hacker
2875 Posts |
Posted - 2009-09-08 : 15:28:03
|
DECLARE @Table TABLE (Date datetime, Val numeric(5,2))INSERT INTO @Tableselect '01/01/2009 15:00:00', 23.40 union allselect '01/01/2009 21:00:00', 40.50 union allselect '01/01/2009 02:00:00', 60.00 union allselect '02/01/2009 05:10:00', 30.45 union allselect '03/01/2009 01:12:00', 30.00 union allselect '05/01/2009 15:00:00', 24.60 SELECT CASE WHEN DATEDIFF(n,'1900/01/01', convert(datetime,'1900/01/01 ' +convert(varchar(8),date,108))) <=300 THEN DATEADD(day,DATEDIFF(day,0,DATEADD(day,-1,date)) ,0) ELSE DATEADD(day,DATEDIFF(day,0,DATE ),0) END , sum(val) from@tablegroup by CASE WHEN DATEDIFF(n,'1900/01/01', convert(datetime,'1900/01/01 ' +convert(varchar(8),date,108))) <=300 THEN DATEADD(day,DATEDIFF(day,0,DATEADD(day,-1,date)) ,0) ELSE DATEADD(day,DATEDIFF(day,0,DATE ),0) END JimEveryday I learn something that somebody else already knew |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2009-09-08 : 16:28:33
|
[code]declare @t table (dt datetime, v money)insert @tselect '01/01/2009 15:00:00', 23.40 union allselect '01/01/2009 21:00:00', 40.50 union allselect '01/01/2009 02:00:00', 60.00 union allselect '02/01/2009 05:10:00', 30.45 union allselect '03/01/2009 01:12:00', 30.00 union allselect '05/01/2009 15:00:00', 24.60SELECT DATEADD(DAY, DATEDIFF(HOUR, '05:00', dt) / 24, 0) AS theDay, SUM(v) AS theSumFROM @tGROUP BY DATEADD(DAY, DATEDIFF(HOUR, '05:00', dt) / 24, 0)[/code] N 56°04'39.26"E 12°55'05.63" |
|
|
|
|
|