sql >> Database teknologi >  >> RDS >> Oracle

Resultat af tidssubtraktionsformat

Når du trækker et tidsstempel fra et andet, er resultatet en intern intervaldatatype, men du kan behandle det som 'intervaldag til sekund':

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

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

'+08' (i min sessions tidszone) er antallet af dage, ikke en UTC offset; det er værdien, fordi når du konverterer en streng til en dato eller et tidsstempel og kun angiver tidsdelen, er datodelen som standard den første dag i den aktuelle måned:

Standarddatoværdierne bestemmes som følger:

  • Året er det aktuelle år, som returneret af SYSDATE.
  • Måneden er den aktuelle måned, som returneret af SYSDATE.
  • Dagen er 01 (den første dag i måneden).
  • Time, minut og sekund er alle 0.

Disse standardværdier bruges i en forespørgsel, der anmoder om datoværdier, hvor selve datoen ikke er angivet ...

Så jeg sammenligner virkelig:

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

Du kan ikke formatere et interval direkte, men du kan udtrække tidens elementer og formatere dem separat og sammenkæde dem.

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

At beregne det samme interval gentagne gange ser lidt spild ud og svært at administrere, så du kan gøre det i en inline-visning eller en 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

Du kan også bruge datoer i stedet for tidsstempler; subtraktion giver dig så forskellen som et tal, med hele og brøkdage:

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

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

Den enkleste måde at formatere på er at tilføje den til en kendt midnatstid og derefter bruge to_char() :

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

Jeg har holdt mig til current_date som det nærmeste match til localtimestamp; du vil måske faktisk have systimestamp og/eller sysdate . (Mere om forskellen her.)




  1. Row Goals, Del 4:Anti Join Anti Pattern

  2. Hold orden fra 'IN'-klausulen

  3. Sådan kortlægger du et PostgreSQL-array med Hibernate

  4. Opret MySQL-forespørgselsovervågningsbash-script