Om du börjar med ett datumvärde, eller i det här fallet ett värde som har konverterats till ett datum, kan du hitta vilket 15-minutersblock på dagen som det hör till som manipulerar antalet sekunder efter midnatt; som du kan hämta från to_char()
med SSSSS
formatmodell.
select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as now_time,
to_char(sysdate, 'SSSSS') as now_secs
from dual;
NOW_TIME NOW_S
------------------- -----
2015-06-18 18:25:49 66349
Du kan avrunda antalet sekunder nedåt till början av en 15-minutersperiod genom att dividera med 900 (15 * 60), trunkera eller lägga ner det för att få ett heltalsvärde och multiplicera tillbaka med 900:
select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as now_time,
to_char(sysdate, 'SSSSS') as now_secs,
to_number(to_char(sysdate, 'SSSSS'))/900 as calc1,
floor(to_number(to_char(sysdate, 'SSSSS'))/900) as calc2,
floor(to_number(to_char(sysdate, 'SSSSS'))/900) * 900 as calc3
from dual;
NOW_TIME NOW_S CALC1 CALC2 CALC3
------------------- ----- ---------- ---------- ----------
2015-06-18 18:25:49 66349 73.7211111 73 65700
Och du kan konvertera tillbaka det till en tid genom att lägga till det tillbaka till ett datum:
select to_char(sysdate, 'YYYY-MM-DD HH24:MI:SS') as now_time,
to_char(sysdate, 'SSSSS') as now_secs,
floor(to_number(to_char(sysdate, 'SSSSS'))/900) * 900 as calc3,
to_char(date '1970-01-01'
+ (floor(to_number(to_char(sysdate, 'SSSSS'))/900) * 900 / 86400),
'HH24:MI:SS') as calc4
from dual;
NOW_TIME NOW_S CALC3 CALC4
------------------- ----- ---------- --------
2015-06-18 18:25:49 66349 65700 18:15:00
Du vill dock antagligen bevara datumet, så att du kan lägga till det i trunc(<original_date>)
istället. Såvida du inte bara har data inom en dag, eller vill visa samma tid från flera dagar tillsammans, antar jag.
Här är en demo med 10 slumpmässigt genererade tider, som visar 15-minutersblocket de är tilldelade:
with t (date_field) as (
select sysdate - dbms_random.value(0, 1)
from dual
connect by level <= 10
)
select to_char(date_field, 'YYYY-MM-DD HH24:MI:SS') as datefield,
to_char(date_field, 'SSSSS') as time_secs,
floor(to_number(to_char(date_field, 'SSSSS'))/900) * 900
as fifteen_min_block_secs,
to_char(trunc(date_field)
+ (floor(to_number(to_char(date_field, 'SSSSS'))/900) * 900) / 86400,
'YYYY-MM-DD HH24:MI:SS') as fifteen_min_block
from t
order by datefield;
DATEFIELD TIME_ FIFTEEN_MIN_BLOCK_SECS FIFTEEN_MIN_BLOCK
------------------- ----- ---------------------- -------------------
2015-06-17 21:03:00 75780 75600 2015-06-17 21:00:00
2015-06-18 05:07:28 18448 18000 2015-06-18 05:00:00
2015-06-18 05:48:42 20922 20700 2015-06-18 05:45:00
2015-06-18 07:23:03 26583 26100 2015-06-18 07:15:00
2015-06-18 08:24:57 30297 29700 2015-06-18 08:15:00
2015-06-18 08:52:06 31926 31500 2015-06-18 08:45:00
2015-06-18 10:59:14 39554 38700 2015-06-18 10:45:00
2015-06-18 11:47:05 42425 42300 2015-06-18 11:45:00
2015-06-18 12:08:37 43717 43200 2015-06-18 12:00:00
2015-06-18 17:07:23 61643 61200 2015-06-18 17:00:00
Så du måste ha
trunc(date_field)
+ (floor(to_number(to_char(date_field, 'SSSSS'))/900) * 900) / 86400
eller det lite enklare
trunc(date_field)
+ floor(to_number(to_char(date_field, 'SSSSS'))/900) / 96
del i din group by
klausul och förmodligen i din vallista för visning.
Förutsatt att T2318.C3 är sekunder sedan epoken, kan du manipulera det direkt och sedan skicka det till din secs_to_datetime
funktion:
secs_to_datetime(floor(T2318.C3 / 900) * 900)
Så motsvarande demo till den ovan, återigen med tio slumpmässigt genererade gånger i en CTE, skulle vara:
with T2318(c3) as (
select 1434708000 - dbms_random.value(0, 80000) from dual
connect by level <= 10
)
select to_char(secs_to_datetime(T2318.C3),'DD/MM/YYYY HH24:MI:SS') as datefield,
T2318.C3 as time_secs,
floor(T2318.C3/900) * 900 as fifteen_min_secs,
to_char(secs_to_datetime(floor(T2318.C3 / 900) * 900),
'DD/MM/YYYY HH24:MI:SS') as fifteen_min
from T2318
order by T2318.C3;
DATEFIELD TIME_SECS FIFTEEN_MIN_SECS FIFTEEN_MIN
------------------- ------------ ---------------- -------------------
18/06/2015 12:34:02 1434630842 1434630600 18/06/2015 12:30:00
18/06/2015 15:06:25 1434639985 1434639600 18/06/2015 15:00:00
18/06/2015 16:43:27 1434645807 1434645000 18/06/2015 16:30:00
18/06/2015 18:57:25 1434653845 1434653100 18/06/2015 18:45:00
18/06/2015 19:01:09 1434654069 1434654000 18/06/2015 19:00:00
18/06/2015 20:54:09 1434660849 1434660300 18/06/2015 20:45:00
19/06/2015 03:59:48 1434686388 1434685500 19/06/2015 03:45:00
19/06/2015 06:58:09 1434697089 1434696300 19/06/2015 06:45:00
19/06/2015 07:36:36 1434699396 1434699000 19/06/2015 07:30:00
19/06/2015 07:47:26 1434700046 1434699900 19/06/2015 07:45:00
Eller om det är i millisekunder, dividera och multiplicera med 900000.