Jeśli zaczynasz od wartości daty lub w tym przypadku wartości, która została przekonwertowana na datę, możesz znaleźć 15-minutowy blok dnia, do którego należy, manipulując liczbą sekund po północy; które możesz uzyskać z to_char()
z SSSSS
model formatu.
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
Liczbę sekund można zaokrąglić w dół do początku 15-minutowego okresu, dzieląc przez 900 (15 * 60), obcinając ją lub równając do wartości całkowitej, a następnie mnożąc ją przez 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
Możesz przekonwertować to z powrotem na czas, dodając go z powrotem do daty:
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
Prawdopodobnie jednak chcesz zachować datę, więc możesz dodać ją do trunc(<original_date>)
zamiast. Chyba że masz dane tylko w ciągu jednego dnia lub chcesz pokazać ten sam czas z wielu dni, jak sądzę.
Oto demonstracja z 10 losowo wygenerowanymi czasami, pokazująca 15-minutowy blok, do którego są przypisane:
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
Więc musisz mieć
trunc(date_field)
+ (floor(to_number(to_char(date_field, 'SSSSS'))/900) * 900) / 86400
lub nieco prostsze
trunc(date_field)
+ floor(to_number(to_char(date_field, 'SSSSS'))/900) / 96
należy do Twojej group by
klauzuli i prawdopodobnie na liście wyboru do wyświetlenia.
Zakładając, że T2318.C3 to sekundy od epoki, możesz manipulować tym bezpośrednio, a następnie przekazać go do swojego secs_to_datetime
funkcja:
secs_to_datetime(floor(T2318.C3 / 900) * 900)
Tak więc równoważne demo do powyższego, ponownie z dziesięcioma losowo generowanymi czasami w CTE, wyglądałoby następująco:
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
Lub jeśli to w milisekundach, podziel i pomnóż przez 900000.