views:

262

answers:

3

I have a continous time dataset and I want to break it up into 15 minute blocks using sql.

I don't want to have to create a new table to be able to do this if I can help it.

i.e.
Time, Count
09:15, 1
09:30, 3
09:45, 0
10:00, 2
10:15, 3
.....

Does anyone have any idea of how I can do this. I presume that is use a select similar to the following:


SELECT [Some kind of data manipulation on "MyDate"]
, COUNT(ID)
FROM MyTable
GROUP BY [Some kind of data manipulation on "MyDate"]

+1  A: 

Something like this seems to work, it strips off the time portion, then readds it at the minute level, after removing minutes mod 15 - to end up with a date in 15 minute intervals, from there its a simple group by

create table quarterHourly (ID int identity(1, 1), created datetime)

insert into quarterHourly values ('2009-07-29 10:00:00.000') -- 10:00
insert into quarterHourly values ('2009-07-29 10:00:00.010') -- 10:00
insert into quarterHourly values ('2009-07-29 10:15:00.000') -- 10:15
insert into quarterHourly values ('2009-07-29 10:15:00.010') -- 10:15
insert into quarterHourly values ('2009-07-29 10:30:00.000') -- 10:30
insert into quarterHourly values ('2009-07-29 10:30:00.010') -- 10:30
insert into quarterHourly values ('2009-07-29 10:45:00.000') -- 10:45
insert into quarterHourly values ('2009-07-29 10:45:00.010') -- 10:45
insert into quarterHourly values ('2009-07-29 11:00:00.000') -- 11:00
insert into quarterHourly values ('2009-07-29 11:00:00.010') -- 11:00
insert into quarterHourly values ('2009-07-29 10:31:00.010') -- 10:30
insert into quarterHourly values ('2009-07-29 10:44:00.010') -- 10:30

select dateadd(mi, datediff(mi, 0, created) - datepart(mi, created) % 15, dateadd(dd, 0, datediff(dd, 0, created))), count(*)
from quarterHourly
group by dateadd(mi, datediff(mi, 0, created) - datepart(mi, created) % 15, dateadd(dd, 0, datediff(dd, 0, created)))
Tetraneutron
+1  A: 

You could group by

DATEPART(year, MyDate), 
DATEPART(month, MyDate), 
DATEPART(day, MyDate), 
DATEPART(hour, MyDate), 
CASE 
WHEN DATEPART(minute, MyDate) BETWEEN 0 AND 14 THEN 0
WHEN DATEPART(minute, MyDate) BETWEEN 15 AND 29 THEN 1
WHEN DATEPART(minute, MyDate) BETWEEN 30 AND 44 THEN 2
WHEN DATEPART(minute, MyDate) BETWEEN 45 AND 59 THEN 3
END

And select the same (probably adding together to make a pretty field).

If you plan on using this often, you might want to make a function which takes a datetime and returns a datetime rounded to 15 minute increments. This would obviously make the query much prettier and gains you the option of indexing the result of the function if appropriate.

EvilRyry
+1  A: 

With careful use of dateadd and datediff, this can be accomplished. My solution rounds the times down.

The first piece calculates the number of minutes between the row's date and the epoch (0) and does a mod 15 on it, giving the difference between the row's date and the closest 15 minute interval:

select -1 * datediff(minute, 0, mydate) % 15
from mytable

Next, we need to deal with just the minutes, so we use this date-part stripping technique I learned from SQL Server Magazine February 2007 (Datetime Calculations by Itzik Ben-Gan):

select dateadd(minute, datediff(minute, 0, mydate), 0)
from mytable

Then, we add the difference to the row's date column and group and count and voila!

select dateadd(minute, -1 * datediff(minute, 0, mydate) % 15, dateadd(minute, datediff(minute, 0, mydate), 0)), count(ID)
from mytable
group by dateadd(minute, -1 * datediff(minute, 0, mydate) % 15, dateadd(minute, datediff(minute, 0, mydate), 0))
Ryan Ische