У меня есть сценарий, в котором мне нужно вычесть одно время из другого.
В столбце таблицы тип данных 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
, как мне этого добиться?
Как будет выглядеть желаемый результат? Что ты уже пробовал?
Кроме того, что произойдет, если время указано в разные дни - я думаю, отрицательный результат может указывать на это (или положительный, в вашем примере), но всегда ли разница в любом случае будет меньше 24 часов? И время всегда в одном и том же часовом поясе? (Вот почему обычно не имеет смысла просто хранить время — сохранение полного значения даты и времени (в виде даты/временной метки) сделает вычисления проще и понятнее.
Разница во втором
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
Выходы:
Я сделал это таким образом
CAST(replace(event_time, ':', '') AS NUMBER) AS n1
CAST(replace(event_time, ':', '') AS NUMBER) AS n2
Тогда выполняй минус n2 - n1
Можете ли вы уточнить, каков ожидаемый результат? Другая строка, содержащая количество секунд между двумя значениями времени? Как его следует форматировать? В приведенном вами примере это будет отрицательно, это правильно или в примере ошибка?