Как вычесть время, хранящееся в виде строк в Oracle

У меня есть сценарий, в котором мне нужно вычесть одно время из другого.

В столбце таблицы тип данных varchar2.

event_time_1 varchar2(10)
event_time_2 varchar2(10)

Данные в таблице

event_time_1  event_time_2
10:01         10:04
10:02         10:06 

Теперь мне нужно вычислить event_time_1 - event_time_2, но, поскольку они оба varchar2, как мне этого добиться?

Можете ли вы уточнить, каков ожидаемый результат? Другая строка, содержащая количество секунд между двумя значениями времени? Как его следует форматировать? В приведенном вами примере это будет отрицательно, это правильно или в примере ошибка?

IMSoP 12.04.2024 10:13

Как будет выглядеть желаемый результат? Что ты уже пробовал?

Martin Schapendonk 12.04.2024 10:14

Кроме того, что произойдет, если время указано в разные дни - я думаю, отрицательный результат может указывать на это (или положительный, в вашем примере), но всегда ли разница в любом случае будет меньше 24 часов? И время всегда в одном и том же часовом поясе? (Вот почему обычно не имеет смысла просто хранить время — сохранение полного значения даты и времени (в виде даты/временной метки) сделает вычисления проще и понятнее.

Alex Poole 12.04.2024 11:11
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
3
72
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Разница во втором

DECLARE
 v_diff NUMBER;
BEGIN
 .....
v_diff := round((to_date (event_time_2, 'MI:SS') - to_date (event_time_1, 'MI:SS'))*86400);
...
END ;

Тип данных DATE в Oracle содержит 7 байтов, представляющих столетия, годы, месяцы, дни, часы, минуты и секунды. Тип данных VARCHAR2 можно преобразовать в DATE с помощью функции To_Date(). Вычитание даты из другой даты дает результат в днях. Полученные дни могут быть рассчитаны в часах, минутах или секундах:

WITH    --  S a m p l e    D a t a :
    tbl AS
        ( Select 1 "ID", '11.04.2024' "DT_1", '10:01' "ET_1", '11.04.2024' "DT_2", '10:04' "ET_2" From Dual Union All
          Select 2 "ID", '10.04.2024' "DT_1", '10:02' "ET_1", '12.04.2024' "DT_2", '10:06' "ET_2" From Dual 
        )
--    S Q L :
Select    ID,
          DT_1 || ' ' || ET_1 || ':00' "DT_ET_1", 
          DT_2 || ' ' || ET_2 || ':00' "DT_ET_2",
          Round(To_Date(DT_2 || ' ' || ET_2 || ':00', 'dd.mm.yyyy hh24:mi:ss') - 
          To_Date(DT_1 || ' ' || ET_1 || ':00', 'dd.mm.yyyy hh24:mi:ss'), 9) "DIFF_DAYS", 
          --
          Round(( To_Date(DT_2 || ' ' || ET_2 || ':00', 'dd.mm.yyyy hh24:mi:ss') - 
            To_Date(DT_1 || ' ' || ET_1 || ':00', 'dd.mm.yyyy hh24:mi:ss') ) * 24, 4) "DIFF_HOURS", 
          --
          Round(( To_Date(DT_2 || ' ' || ET_2 || ':00', 'dd.mm.yyyy hh24:mi:ss') - 
            To_Date(DT_1 || ' ' || ET_1 || ':00', 'dd.mm.yyyy hh24:mi:ss') ) * 24 * 60, 4) "DIFF_MINS", 
          --
          Round(( To_Date(DT_2 || ' ' || ET_2 || ':00', 'dd.mm.yyyy hh24:mi:ss') - 
            To_Date(DT_1 || ' ' || ET_1 || ':00', 'dd.mm.yyyy hh24:mi:ss') ) * 24 *60 * 60, 4) "DIFF_SECS" 
From      tbl
/*    --  R e s u l t : 
ID   DT_ET_1                DT_ET_2             DIFF_DAYS   DIFF_HOURS DIFF_MINS DIFF_SECS
--   -------------------    ------------------- ----------- ---------- --------- ---------
 1   11.04.2024 10:01:00    11.04.2024 10:04:00 0,002083333     0,0500         3       180
 2   10.04.2024 10:02:00    12.04.2024 10:06:00 2,002777778    48,0667      2884    173040  */
Ответ принят как подходящий

Преобразуйте строки в даты, а затем вычтите их, чтобы получить либо интервал, либо разницу в количестве дней (которую можно умножить на 24*60, чтобы получить минуты):

SELECT event_time_1,
       event_time_2,
       (
         TO_DATE(event_time_2, 'HH24:MI')
         - TO_DATE(event_time_1, 'HH24:MI')
       ) DAY TO SECOND AS interval_diff,
       (
         TO_DATE(event_time_2, 'HH24:MI')
         - TO_DATE(event_time_1, 'HH24:MI')
       ) AS days_diff,
       (
         TO_DATE(event_time_2, 'HH24:MI')
         - TO_DATE(event_time_1, 'HH24:MI')
       ) * 24 * 60 AS minutes_diff
FROM   table_name

Что для примера данных:

CREATE TABLE table_name (
  event_time_1 varchar2(10),
  event_time_2 varchar2(10)
);

INSERT INTO table_name (event_time_1, event_time_2)
SELECT '10:01', '10:04' FROM DUAL UNION ALL
SELECT '10:02', '10:06' FROM DUAL

Выходы:

EVENT_TIME_1 EVENT_TIME_2 INTERVAL_DIFF DAYS_DIFF MINUTES_DIFF 10:01 10:04 +00 00:03:00.000000 .0020833333333333333333333333333333333333333 3 10:02 10:06 +00 00:04:00.000000 .002777777777777777777777777777777777777777778 4

рабочий пример

Я сделал это таким образом

 CAST(replace(event_time, ':', '') AS NUMBER) AS n1
 CAST(replace(event_time, ':', '') AS NUMBER) AS n2

Тогда выполняй минус n2 - n1

Другие вопросы по теме