Timeslot SQL
April 30, 2012 Leave a comment
A reminder about sql logic required to deal with express datetimes to the nearest x mins – for example, this particular question come up on an internal forum last week where the poster wanted to aggregate data per quarter hour.
There are two approaches depending on the exact requirement.
The first option is to generate the timeslots using a data generator and then join to the source data.
SQL> alter session set nls_date_format = 'DD-MON-YYYY Hh24:MI'; Session altered. SQL> with times as 2 (select trunc(sysdate) + ((rownum-1)*15/60/24) slot 3 from dual 4 connect by rownum <= 10) --<-- just to keep the output short 5 select * from times; SLOT ----------------- 30-APR-2012 00:00 30-APR-2012 00:15 30-APR-2012 00:30 30-APR-2012 00:45 30-APR-2012 01:00 30-APR-2012 01:15 30-APR-2012 01:30 30-APR-2012 01:45 30-APR-2012 02:00 30-APR-2012 02:15 10 rows selected.
The second options is to round/floor/ceil the relevant existing date/timestamp in the table to the nearest x minutes.
For this solution, there is a generic approach as follows, demonstrated using sysdate:
SQL> select sysdate, 2 trunc(sysdate) 3 + floor(to_char(sysdate,'sssss') / 900) / 96 floor_slot, 4 trunc(sysdate) 5 + round(to_char(sysdate,'sssss') / 900) / 96 round_slot, 6 trunc(sysdate) 7 + ceil(to_char(sysdate,'sssss') / 900) / 96 ceil_slot 8 from dual; SYSDATE FLOOR_SLOT ROUND_SLOT CEIL_SLOT ----------------- ----------------- ----------------- ----------------- 30-APR-2012 09:58 30-APR-2012 09:45 30-APR-2012 10:00 30-APR-2012 10:00 SQL>
Where the basic forumla is:
trunc(sysdate) + floor(to_char(sysdate,'sssss') / x ) / y
- The date – example uses sysdate but this would probably be a column – truncated to start of day.
- The usage of FLOOR / ROUND / CEIL depends on the requirement.
- to_char(sysdate,’sssss’) is the number of seconds since midnight
- x is the number of seconds in the timeslot length we’re interested in – for the example, 15 minutes * 60 seconds per minute = 900
- Because date arithmetic is done in days, y is the number of timeslots in a day – for this example 4 timeslots per hour * 24 hours per day = 96
So, if we want five minute timeslots, x is 5*60=300; y is 12*24=288:
SQL> select sysdate, 2 trunc(sysdate) 3 + floor(to_char(sysdate,'sssss') / 300) / 288 floor_stamp, 4 trunc(sysdate) 5 + round(to_char(sysdate,'sssss') / 300) / 288 round_stamp, 6 trunc(sysdate) 7 + ceil(to_char(sysdate,'sssss') / 300) / 288 ceil_stamp 8 from dual; SYSDATE FLOOR_STAMP ROUND_STAMP CEIL_STAMP ----------------- ----------------- ----------------- ----------------- 30-APR-2012 10:13 30-APR-2012 10:10 30-APR-2012 10:15 30-APR-2012 10:15 SQL>
Or, for half hour timeslots, x is 60*30=1800; y is 2*24=48:
SQL> select sysdate, 2 trunc(sysdate) 3 + floor(to_char(sysdate,'sssss') / 1800) / 48 floor_stamp, 4 trunc(sysdate) 5 + round(to_char(sysdate,'sssss') / 1800) / 48 round_stamp, 6 trunc(sysdate) 7 + ceil(to_char(sysdate,'sssss') / 1800) / 48 ceil_stamp 8 from dual; SYSDATE FLOOR_STAMP ROUND_STAMP CEIL_STAMP ----------------- ----------------- ----------------- ----------------- 30-APR-2012 10:19 30-APR-2012 10:00 30-APR-2012 10:30 30-APR-2012 10:30 SQL>
Recent Comments