sql >> Databasteknik >  >> RDS >> Oracle

Resultat av tidssubtraktionsformat

När du subtraherar en tidsstämpel från en annan blir resultatet en intern intervalldatatyp, men du kan behandla den som 'intervalldag till 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 tidszon) är antalet dagar, inte en UTC-offset; det är värdet det är eftersom när du konverterar en sträng till ett datum eller en tidsstämpel och bara anger tidsdelen, är datumdelen som standard den första dagen i den aktuella månaden:

Standardvärdena för datum bestäms enligt följande:

  • Året är innevarande år, som returneras av SYSDATE.
  • Månaden är den aktuella månaden, som returneras av SYSDATE.
  • Dagen är 01 (den första dagen i månaden).
  • Timman, minuten och sekund är alla 0.

Dessa standardvärden används i en fråga som begär datumvärden där själva datumet inte är specificerat ...

Så jag jämför verkligen:

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 inte formatera ett intervall direkt, men du kan extrahera tidselementen och formatera dem separat och sammanfoga 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

Att upprepade gånger beräkna samma intervall ser lite slösaktigt och svårt att hantera, så du kan göra det i en inline-vy 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 också använda datum istället för tidsstämplar; subtraktion ger dig sedan skillnaden som ett tal, med hela och bråktal dagar:

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

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

Det enklaste sättet att formatera är att lägga till det till en känd midnattstid och sedan använda 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

Jag har fastnat för current_date som den närmaste matchningen till localtimestamp; du kanske faktiskt vill ha systimestamp och/eller sysdate . (Mer om skillnaden här.)




  1. Hur kan jag gå in i en SQL Server-lagrad proc från min C#-kod?

  2. ORACLE Efter uppdateringstrigger:löser ORA-04091 mutationstabellfel

  3. Migrera MySQL till PostgreSQL på AWS RDS, del 4

  4. SQL - OM FINNS UPPDATERA ANNARS INSERT INTO