Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Wynik formatu odejmowania czasu

Kiedy odejmujesz jeden znacznik czasu od drugiego, wynikiem jest wewnętrzny przedział danych, ale możesz traktować to jako „przedział z dnia na sekundę”:

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

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

„+08” (w mojej strefie czasowej sesji) to liczba dni, a nie przesunięcie UTC; jest to wartość, ponieważ gdy konwertujesz ciąg na datę lub znacznik czasu i podajesz tylko część czasu, część daty jest domyślnie ustawiana na pierwszy dzień bieżącego miesiąca:

Domyślne wartości dat są określane w następujący sposób:

  • Rok jest rokiem bieżącym, zwracanym przez SYSDATE.
  • Miesiąc jest bieżącym miesiącem, zwracanym przez SYSDATE.
  • Dzień to 01 (pierwszy dzień miesiąca).
  • Godzina, minuta i sekunda to 0.

Te wartości domyślne są używane w zapytaniu, które żąda wartości dat, gdy sama data nie jest określona...

Więc naprawdę porównuję:

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

Nie możesz bezpośrednio sformatować interwału, ale możesz wyodrębnić elementy czasu i sformatować je oddzielnie i połączyć je.

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

Wielokrotne obliczanie tego samego interwału wydaje się trochę marnotrawne i trudne do zarządzania, więc możesz to zrobić w widoku wbudowanym lub 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

Możesz także użyć dat zamiast znaczników czasu; odejmowanie daje różnicę jako liczbę, z dniami pełnymi i ułamkowymi:

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

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

Najprostszym sposobem formatowania jest dodanie go do znanej godziny północy, a następnie użycie 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

Utknąłem z current_date jako najbliższe dopasowanie do localtimestamp; możesz rzeczywiście chcieć systimestamp i/lub sysdate . (Więcej o różnicach tutaj.)




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak zadeklarować wyjątek zdefiniowany przez użytkownika przy użyciu zmiennej wyjątku w bazie danych Oracle

  2. customer.pk_name dołączanie do transakcji.fk_name vs. customer.pk_id [serial] dołączanie do transakcji.fk_id [liczba całkowita]

  3. dynamiczne przekazywanie nazwy tabeli i kolumny za pomocą zmiennych bind

  4. Zapytanie SQL w celu zwinięcia zduplikowanych wartości według zakresu dat

  5. jak połączyć więcej niż dwie kolumny w deweloperze plsql?