sql >> Database >  >> RDS >> Oracle

Maak bereiken van minuten (15) in select

Als je begint met een datumwaarde, of in dit geval een waarde die is geconverteerd naar een datum, kun je zien bij welk blok van de dag van 15 minuten het hoort door het aantal seconden na middernacht te manipuleren; die je kunt krijgen van to_char() met de SSSSS formaatmodel.

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

U kunt het aantal seconden naar beneden afronden tot het begin van een periode van 15 minuten door te delen door 900 (15 * 60), het af te kappen of te verlagen om een ​​geheel getal te krijgen, en terug vermenigvuldigen met 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

En je kunt dat terug converteren naar een tijd door het weer toe te voegen aan een 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

U wilt waarschijnlijk de datum behouden, zodat u deze kunt toevoegen aan trunc(<original_date>) in plaats van. Tenzij je alleen gegevens binnen één dag hebt, of dezelfde tijd van meerdere dagen bij elkaar wilt laten zien, neem ik aan.

Hier is een demo met 10 willekeurig gegenereerde tijden, die het blok van 15 minuten laten zien waaraan ze zijn toegewezen:

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

U moet dus de

trunc(date_field)
  + (floor(to_number(to_char(date_field, 'SSSSS'))/900) * 900) / 86400

of de iets eenvoudigere

trunc(date_field)
  + floor(to_number(to_char(date_field, 'SSSSS'))/900) / 96

deel aan uw group by clausule, en waarschijnlijk in uw geselecteerde lijst voor weergave.

Ervan uitgaande dat T2318.C3 seconden sinds het tijdperk is, zou je dat direct kunnen manipuleren en dat dan doorgeven aan je secs_to_datetime functie:

secs_to_datetime(floor(T2318.C3 / 900) * 900)

Dus de equivalente demo als hierboven, opnieuw met tien willekeurig gegenereerde tijden in een CTE, zou zijn:

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

Of als het in milliseconden is, deel en vermenigvuldig met 900000.



  1. Zoek kruispunten tussen rijen en tijdstempels in een mysql db

  2. Hoe het verschil tussen twee datums in T-SQL te berekenen

  3. 3 manieren om alle tabellen te retourneren ZONDER een primaire sleutel in SQL Server

  4. een zeer grote orakeltabel bijwerken