Извлечение эквивалентного ЧАСА продолжительности времени - PullRequest
0 голосов
/ 08 января 2019

У меня есть следующий формат поля даты: «ЧЧ: ММ», который представляет длительность события, и мне нравится извлекать эквивалентное значение в ЧАС (например: 2h: 30min ==> Результат: 2,5 часа ).

Привет.

Ответы [ 3 ]

0 голосов
/ 08 января 2019

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

Один из методов извлечения компонентов состоит в том, чтобы взять первые два символа, а затем 4-й и 5-й. regexp_substr() обеспечивает немного больше гибкости:

select cast(regexp_substr(yyyymm, '[^:]+', 1, 1) as number) + cast(regexp_substr(yyyymm, '[^:]+', 1, 2) as number) / 60
from (select '24:30' as yyyymm from dual) x
0 голосов
/ 08 января 2019

В идеале измените таблицу, чтобы хранить данные как тип данных INTERVAL DAY TO SECOND, а затем вы можете просто сохранить INTERVAL '2:30' HOUR TO MINUTE и использовать арифметику даты, чтобы получить свой ответ.

SELECT ( DATE '1970-01-01' + your_interval_value - DATE '1970-01-01' ) * 24
FROM   DUAL;

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

дБ <> скрипка здесь

Установка Oracle :

 CREATE TABLE table_name ( value ) AS
 SELECT '2h:30min' FROM DUAL UNION ALL
 SELECT '15min' FROM DUAL UNION ALL
 SELECT '3h' FROM DUAL UNION ALL
 SELECT '26 h : 20 min' FROM DUAL UNION ALL
 SELECT '-2h:30min' FROM DUAL UNION ALL
 SELECT '-4h' FROM DUAL UNION ALL
 SELECT '-45min' FROM DUAL UNION ALL
 SELECT '0h:0min' FROM DUAL UNION ALL
 SELECT '0h' FROM DUAL UNION ALL
 SELECT '-0min' FROM DUAL;

Запрос

 SELECT value,
        ( DATE '1970-01-01'
        + NUMTODSINTERVAL(
            CASE WHEN INSTR( value, '-' ) > 0 THEN -1 ELSE 1 END
            *
            TO_NUMBER( COALESCE( REGEXP_SUBSTR( value, '(\d*)\s*h', 1, 1, 'i', 1 , '0' ) ),
            'HOUR'
          )
        + NUMTODSINTERVAL(
            CASE WHEN INSTR( value, '-' ) > 0 THEN -1 ELSE 1 END
            *
            TO_NUMBER( COALESCE( REGEXP_SUBSTR( value, '(\d*)\s*min', 1, 1, 'i', 1 ), '0' ) ),
            'MINUTE'
          )
        - DATE '1970-01-01'
        ) * 24 AS hours_difference
 FROM   table_name;

выход

VALUE         |                          HOURS_DIFFERENCE
:------------ | ----------------------------------------:
2h:30min      |                                       2.5
15min         | .2500000000000000000000000000000000000008
3h            |                                         3
26 h : 20 min | 26.33333333333333333333333333333333333328
-2h:30min     |                                      -2.5
-4h           |                                        -4
-45min        |                                      -.75
0h:0min       |                                         0
0h            |                                         0
-0min         |                                         0
0 голосов
/ 08 января 2019

Путь оракула:

SELECT (TO_DATE('2h:30min', 'HH24"h":MI"min"') - TO_DATE('0:00', 'HH24:MI')) * 24.0 from dual

Как это работает:

  • Разбирает 2h:30min в дату и генерирует дату 01-JAN-19 (все разбор даты без дня, месяца, года становится 1-м числа текущего месяца / года)
  • Анализирует 0:00 до даты -> в тот же день, тот же месяц, тот же год, что и выше, но в полночь
  • Вычитает их, в результате чего получается число с плавающей запятой, которое представляет собой доли дня (день равен 1,0, 12 часов - 0,5 и т. Д.) Между двумя датами. Это работает в этом случае как приблизительно 0.1041667
  • Мы умножаем на 24, чтобы превратить наши 0,1041667 дней в часы -> 2,5
...