Oracle SQL Hours Разница между датами в формате ЧЧ: ММ: СС - PullRequest
0 голосов
/ 13 июня 2018

У меня уже есть строка для вычисления разницы в часах между двумя датами, которые я получил из стека:

24 *  (to_date(to_char(stp.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss') -
(to_date(to_char(adhh.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss'))) diff_hours

Но я хочу видеть это как ЧЧ: ММ: СС

Вот 2 даты / времени в качестве примера: Дата STP 26-Фев-18 12.59.21 ADHH Дата 26-Фев-18 12.59.32

Итак, я хочу сказать, что разница00:00:11 (11 секунд)

в данный момент я получаю результат как -0,003 часа

Заранее спасибо, как всегда

Ответы [ 5 ]

0 голосов
/ 13 июня 2018

Вы можете преобразовать его в интервал, а затем просто использовать TO_CHAR для преобразования интервала в строку:

Скрипка SQL

Oracle 11gНастройка схемы R2 :

CREATE TABLE STP ( id INT, created_date DATE );
CREATE TABLE ADHH ( id INT, created_date DATE );

INSERT INTO STP  values ( 1, TIMESTAMP '2018-02-26 12:59:21' );
INSERT INTO STP  values ( 2, TIMESTAMP '2018-02-26 12:00:30' );
INSERT INTO ADHH values ( 1, TIMESTAMP '2018-02-26 12:59:32' );
INSERT INTO ADHH values ( 2, TIMESTAMP '2018-02-26 12:00:00' );

Запрос 1 :

SELECT TO_CHAR(
         ( s.created_date - a.created_date ) DAY(1) TO SECOND(0)
       ) AS diff
FROM   STP s
       INNER JOIN ADHH a
       ON ( s.id = a.id )

Результаты :

|        DIFF |
|-------------|
| -0 00:00:11 |
| +0 00:00:30 |

Запрос 2 : Если у вас нет компонента дней (т. Е. Даты всегда меньше 24 часов), просто замените подстроку 0:

SELECT REPLACE(
         ( s.created_date - a.created_date ) DAY(1) TO SECOND(0),
         '0 '
       ) AS diff
FROM   STP s
       INNER JOIN ADHH a
       ON ( s.id = a.id )

Результаты :

|      DIFF |
|-----------|
| -00:00:11 |
| +00:00:30 |
0 голосов
/ 13 июня 2018

Похоже, ваши столбцы уже в формате DATE (они должны быть!).В этом случае вы можете просто получить разницу между датами в виде DAY TO SECOND INTERVAL.Для этого используйте функцию NUMTODSINTERVAL.Затем с помощью функции EXTRACT вы можете получить интервал в часах, минутах и ​​секундах.

Вот пример запроса.

WITH
    stp (created_date)
    AS
        (SELECT CAST (TIMESTAMP '2018-02-26 12:59:21' AS DATE) FROM DUAL),
    adhh (created_date)
    AS
        (SELECT CAST (TIMESTAMP '2018-02-26 12:59:32' AS DATE) FROM DUAL)
SELECT    LPAD (EXTRACT (HOUR FROM diff_int), 2, '0')   -- get hours from interval
       || ':'
       || LPAD (EXTRACT (MINUTE FROM diff_int), 2, '0') -- get minutes from interval
       || ':'
       || LPAD (EXTRACT (SECOND FROM diff_int), 2, '0') -- get seconds from interval
           AS diff_hours
FROM (SELECT NUMTODSINTERVAL (  -- get difference between the dates as an interval
                 b.created_date
                 - a.created_date,
                 'DAY'
             )
                 diff_int
      FROM stp a,
           adhh b);

Вот результат.

DIFF_HOURS

00: 00: 11

0 голосов
/ 13 июня 2018

Предполагая, что столбцы уже являются датами, и, следовательно, преобразование в и из строк, которые вы делаете, бессмысленно, и что разница всегда будет меньше, чем день, вы могли бы сделать:

to_char(date '1970-01-01' + abs(stp.created_date - adhh.created_date), 'HH24:MI:SS')

Получается разница между датами в виде доли дня;удостоверяется, что это положительно через abs();а затем добавляет эту дробь обратно к номинальной дате, которая имеет время как полночь.Затем он преобразует это в строку, глядя только на время.

Быстрое демо:

-- CTEs to supply the two date/times
with stp (created_date) as (
  select cast(timestamp '2018-02-26 12:59:21' as date) from dual
),
adhh (created_date) as (
  select cast(timestamp '2018-02-26 12:59:32' as date) from dual
)
select to_char(date '1970-01-01' + abs(stp.created_date - adhh.created_date), 'HH24:MI:SS')
from stp cross join adhh;

TO_CHAR(
--------
00:00:11

Если разница может превышать день, но не год, вы можете изменить форматмодель на что-то вроде 'FMDDD FMHH24:MI:SS', которая покажет полные дни в начале.

0 голосов
/ 13 июня 2018

Предполагая, что столбцы уже имеют значения DATE (если нет, я настоятельно рекомендую изменить их), вы можете преобразовать их в метку времени.Этого должно быть достаточно для преобразования только одного значения, но, конечно, вы можете преобразовать оба.

CAST(stp.created_date AS TIMESTAMP) - adhh.created_date AS dif

Результатом является значение INTERVAL DAY TO SECOND, которое имеет фиксированный формат вывода DDD HH:MI:SS.FF.Для получения желаемого формата вы можете использовать

REGEXP_SUBSTR(CAST(stp.created_date AS TIMESTAMP) - adhh.created_date, '\d{2}:\d{2}:\d{2}') AS dif

Примечание. TO_CHAR не работает с интервалами.Таким образом, вы должны использовать REGEXP или извлечь компоненты с помощью EXTRACT (... FROM ...)

0 голосов
/ 13 июня 2018

Я предложу вам небольшое изменение в вашем запросе

SELECT 
TO_CHAR(TRUNC(x/3600),'FM9900') || ':' ||
TO_CHAR(TRUNC(MOD(x,3600)/60),'FM00') || ':' ||
TO_CHAR(MOD(x,60),'FM00')
 FROM DUAL   

просто замените 'x' в запросе выше на ваш столбец результатов

24 *  (
to_date(to_char(stp.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DD hh24:mi:ss') -
(to_date(to_char(adhh.created_date,'YYYY-MM-DD hh24:mi:ss'),'YYYY-MM-DDhh24:mi:ss')))

надеюсь, это поможет ..

...