Вычисление разницы между двумя метками времени в Oracle в миллисекундах

Как рассчитать разницу во времени в миллисекундах между двумя метками времени в Oracle?

8 ответов


при вычитании двух переменных типа TIMESTAMP вы получаете INTERVAL DAY TO SECOND который включает в себя несколько миллисекунд и/или микросекунд в зависимости от платформы. Если база данных работает в Windows, systimestamp обычно будет иметь миллисекунды. Если база данных работает в Unix,systimestamp обычно будет иметь микросекунды.

  1  select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' )
  2*   from dual
SQL> /

SYSTIMESTAMP-TO_TIMESTAMP('2012-07-23','YYYY-MM-DD')
---------------------------------------------------------------------------
+000000000 14:51:04.339000000

можно использовать EXTRACT функция для извлечения отдельных элементов INTERVAL DAY TO SECOND

SQL> ed
Wrote file afiedt.buf

  1  select extract( day from diff ) days,
  2         extract( hour from diff ) hours,
  3         extract( minute from diff ) minutes,
  4         extract( second from diff ) seconds
  5    from (select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' ) diff
  6*           from dual)
SQL> /

      DAYS      HOURS    MINUTES    SECONDS
---------- ---------- ---------- ----------
         0         14         55     37.936

затем вы можете конвертировать каждый из этих компонентов в миллисекунды и сложить их

SQL> ed
Wrote file afiedt.buf

  1  select extract( day from diff )*24*60*60*1000 +
  2         extract( hour from diff )*60*60*1000 +
  3         extract( minute from diff )*60*1000 +
  4         round(extract( second from diff )*1000) total_milliseconds
  5    from (select systimestamp - to_timestamp( '2012-07-23', 'yyyy-mm-dd' ) diff
  6*           from dual)
SQL> /

TOTAL_MILLISECONDS
------------------
          53831842

обычно, однако, более полезно иметь либо INTERVAL DAY TO SECOND представительство или иметь отдельные столбцы для часов, минут, секунд и т. д. вместо того, чтобы вычислять общее количество миллисекунд между двумя TIMESTAMP значения.


вот сохраненный proc для этого:

CREATE OR REPLACE function timestamp_diff(a timestamp, b timestamp) return number is 
begin
  return extract (day    from (a-b))*24*60*60 +
         extract (hour   from (a-b))*60*60+
         extract (minute from (a-b))*60+
         extract (second from (a-b));
end;
/

голосуйте, если вы также хотите выбить дерьмо из разработчика Oracle, который отрицал свою работу!

потому что сравнение временных меток в первый раз должно занять у всех час или около того...


простое решение:

SELECT numtodsinterval(date1-date2,'day') time_difference from dates;

для отметки времени:

SELECT (extract(DAY FROM time2-time1)*24*60*60)+ 
(extract(HOUR FROM time2-time1)*60*60)+
(extract(MINUTE FROM time2-time1)*60)+
extract(SECOND FROM time2-time1)
into diff FROM dual;

RETURN diff;

выберите date1- (date2 - 1) * 24 * 60 *60 * 1000 со стола;


лучше использовать такое:

CREATE OR REPLACE FUNCTION timestamp_diff
(
start_time_in TIMESTAMP
, end_time_in TIMESTAMP
)
RETURN NUMBER
AS
l_days NUMBER;
l_hours NUMBER;
l_minutes NUMBER;
l_seconds NUMBER;
l_milliseconds NUMBER;
BEGIN
SELECT extract(DAY FROM end_time_in-start_time_in)
, extract(HOUR FROM end_time_in-start_time_in)
, extract(MINUTE FROM end_time_in-start_time_in)
, extract(SECOND FROM end_time_in-start_time_in)
INTO l_days, l_hours, l_minutes, l_seconds
FROM dual;

l_milliseconds := l_seconds*1000 + l_minutes*60*1000 + l_hours*60*60*1000 + l_days*24*60*60*1000;
RETURN l_milliseconds;

END;

вы можете проверить его, позвонив:

SELECT timestamp_diff (TO_TIMESTAMP('12.04.2017 12:00:00.00', 'DD.MM.YYYY HH24:MI:SS.FF'), 
                      TO_TIMESTAMP('12.04.2017 12:00:01.111', 'DD.MM.YYYY HH24:MI:SS.FF')) 
            as milliseconds
    FROM DUAL;

метка времени, правильно отлитая между форматами, иначе есть вероятность, что поля будут неправильно интерпретированы.

вот рабочий образец, который является правильным, когда две разные даты (Date2, Date1) рассматриваются из таблицы TableXYZ.

SELECT ROUND (totalSeconds / (24 * 60 * 60), 1) TotalTimeSpendIn_DAYS,
       ROUND (totalSeconds / (60 * 60), 0) TotalTimeSpendIn_HOURS,
       ROUND (totalSeconds / 60) TotalTimeSpendIn_MINUTES,
       ROUND (totalSeconds) TotalTimeSpendIn_SECONDS
  FROM (SELECT ROUND (
                    EXTRACT (DAY FROM timeDiff) * 24 * 60 * 60
                  + EXTRACT (HOUR FROM timeDiff) * 60 * 60
                  + EXTRACT (MINUTE FROM timeDiff) * 60
                  + EXTRACT (SECOND FROM timeDiff))
                  totalSeconds,
          FROM (SELECT TO_TIMESTAMP (
                            TO_CHAR (Date2,
                                     'yyyy-mm-dd HH24:mi:ss')
                          - 'yyyy-mm-dd HH24:mi:ss'),
                       TO_TIMESTAMP (
                          TO_CHAR (Date1,
                                   'yyyy-mm-dd HH24:mi:ss'),
                          'yyyy-mm-dd HH24:mi:ss')
                          timeDiff
                  FROM TableXYZ))

выше есть некоторая синтаксическая ошибка, пожалуйста, используйте следующее в oracle:

SELECT ROUND (totalSeconds / (24 * 60 * 60), 1) TotalTimeSpendIn_DAYS,
  ROUND (totalSeconds      / (60 * 60), 0) TotalTimeSpendIn_HOURS,
  ROUND (totalSeconds      / 60) TotalTimeSpendIn_MINUTES,
  ROUND (totalSeconds) TotalTimeSpendIn_SECONDS
FROM
  (SELECT ROUND ( EXTRACT (DAY FROM timeDiff) * 24 * 60 * 60 + EXTRACT (HOUR FROM timeDiff) * 60 * 60 + EXTRACT (MINUTE FROM timeDiff) * 60 + EXTRACT (SECOND FROM timeDiff)) totalSeconds
  FROM
    (SELECT TO_TIMESTAMP(TO_CHAR( date2 , 'yyyy-mm-dd HH24:mi:ss'), 'yyyy-mm-dd HH24:mi:ss') - TO_TIMESTAMP(TO_CHAR(date1, 'yyyy-mm-dd HH24:mi:ss'),'yyyy-mm-dd HH24:mi:ss') timeDiff
    FROM TABLENAME
    )
);

I) Если вам нужно рассчитать прошедшее время в секундах между двумя столбцами метки времени, попробуйте следующее:

выберите извлечение ( сутки (end_timestamp - start_timestamp) )*86400 + экстракт ( час от (end_timestamp - start_timestamp) )*3600 + экстракт ( минута от (end_timestamp - start_timestamp) )*60 + экстракт ( второй (end_timestamp - start_timestamp) ) from имя_таблицы

II) Если вы хотите просто показать разницу во времени в символьный формат попробовать это:

выберите to_char (end_timestamp - start_timestamp) из table_name