sql >> Database >  >> RDS >> Oracle

Tijd aftrekken formaat resultaat

Wanneer u de ene tijdstempel van de andere aftrekt, is het resultaat een intern intervalgegevenstype, maar u kunt het behandelen als 'interval van dag tot seconde':

select
(localtimestamp - to_timestamp(us.STARTDATETIME,'hh24:mi:ss')) as HoursPassed
from random us;

HOURSPASSED        
-------------------
+08 15:26:54.293892

De '+08' (in mijn sessietijdzone) is het aantal dagen, geen UTC-offset; dat is de waarde die het is, want wanneer u een tekenreeks converteert naar een datum of tijdstempel en alleen het tijdgedeelte opgeeft, wordt het datumgedeelte standaard ingesteld op de eerste dag van de huidige maand:

De standaard datumwaarden worden als volgt bepaald:

  • Het jaar is het huidige jaar, zoals teruggegeven door SYSDATE.
  • De maand is de huidige maand, zoals geretourneerd door SYSDATE.
  • De dag is 01 (de eerste dag van de maand).
  • Het uur, de minuut en de seconde zijn allemaal 0.

Deze standaardwaarden worden gebruikt in een query die om datumwaarden vraagt ​​waarbij de datum zelf niet is opgegeven ...

Dus ik ben echt aan het vergelijken:

select localtimestamp, to_timestamp(us.STARTDATETIME,'hh24:mi:ss')
from random us;

LOCALTIMESTAMP             TO_TIMESTAMP(US.STARTDATET
-------------------------- --------------------------
2017-08-09 23:26:54.293892 2017-08-01 08:00:00.000000

U kunt een interval niet direct opmaken, maar u kunt de elementen van de tijd extraheren en deze afzonderlijk formatteren en samenvoegen.

select to_char(extract(hour from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  ||':'|| to_char(extract(minute from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  ||':'|| to_char(extract(second from (localtimestamp
    - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss'))), 'FM00')
  as hourspassed
from random us;

HOURSPASSED
-----------
15:26:54

Herhaaldelijk hetzelfde interval berekenen lijkt een beetje verkwistend en moeilijk te beheren, dus je kunt dat doen in een inline-weergave of een CTE:

with cte (diff) as (
  select localtimestamp - to_timestamp(us.STARTDATETIME, 'hh24:mi:ss')
  from random us
)
select to_char(extract(hour from diff), 'FM00')
  ||':'|| to_char(extract(minute from diff), 'FM00')
  ||':'|| to_char(extract(second from diff), 'FM00')
  as hourspassed
from cte;

HOURSPASSED
-----------
15:26:54

U kunt ook datums gebruiken in plaats van tijdstempels; aftrekken geeft je dan het verschil als een getal, met hele en gebroken dagen:

select current_date - to_date(us.STARTDATETIME, 'hh24:mi') as hourspassed
from random us;

HOURSPASSED
-----------
 8.64368056

De eenvoudigste manier om dat te formatteren is door het toe te voegen aan een bekende middernachttijd en vervolgens to_char() te gebruiken :

select to_char(date '1970-01-01'
  + (current_date - to_date(us.STARTDATETIME, 'hh24:mi')),
  'HH24:MI:SS') as hourspassed
from random us;

HOURSPAS
--------
15:26:54

Ik blijf bij current_date als de beste overeenkomst met localtimestamp; misschien wil je eigenlijk systimestamp en/of sysdate . (Meer over het verschil hier.)




  1. Hoe ALLE logische operatoren in SQL Server te gebruiken - SQL Server / TSQL-zelfstudie, deel 126

  2. Hoe indexen voor een database of tabel in MySQL te zien?

  3. Hoe de spring-boot-app te starten zonder afhankelijk te zijn van de database?

  4. PostgreSQL date() met tijdzone