В: Есть ли в Oracle функция, которая вычисляет разницу между двумя датами?
Просто вычтите одно выражение даты из другого, чтобы получить разницу в количестве дней. Целая часть - это количество целых дней, дробная часть - это доля дня. Простая арифметика после этого умножьте на 24, чтобы получить часы.
В: Если нет, можно ли показать разницу между двумя датами в часах и минутах?
Это просто вопрос выражения продолжительности в виде целых часов и оставшихся минут.
Мы можем пойти по «старой школе», чтобы получить длительности в формате hhhh: mi, используя комбинацию простых встроенных функций:
SELECT decode(sign(t.maxst),-1,'-','')||to_char(floor(abs(t.maxst)/60))||
decode(t.maxst,null,'',':')||to_char(mod(abs(t.maxst),60),'FM00')
as MaximumScheduleTime
, decode(sign(t.minst),-1,'-','')||to_char(floor(abs(t.minst)/60))||
decode(t.minst,null,'',':')||to_char(mod(abs(t.minst),60),'FM00')
as MinimumScheduleTime
, decode(sign(t.avgst),-1,'-','')||to_char(floor(abs(t.avgst)/60))
decode(t.avgst,null,'',':')||to_char(mod(abs(t.avgst),60),'FM00')
as AverageScheduleTime
FROM (
SELECT round(max((EndDate - StartDate) *1440),0) as maxst
, round(min((EndDate - StartDate) *1440),0) as minst
, round(avg((EndDate - StartDate) *1440),0) as avgst
FROM table1
) t
Да, это непросто, но довольно быстро. Вот более простой случай, который лучше показывает, что происходит:
select dur as "minutes"
, abs(dur) as "unsigned_minutes"
, floor(abs(dur)/60) as "unsigned_whole_hours"
, to_char(floor(abs(dur)/60)) as "hhhh"
, mod(abs(dur),60) as "unsigned_remainder_minutes"
, to_char(mod(abs(dur),60),'FM00') as "mi"
, decode(sign(dur),-1,'-','') as "leading_sign"
, decode(dur,null,'',':') as "colon_separator"
from (select round(( date_expr1 - date_expr2 )*24*60,0) as dur
from ...
)
(замените date_expr1
и date_expr2
выражениями даты)
давай распакуем это
date_expr1 - date_expr2
возвращает разницу в количестве дней
- умножьте на 1440 (24 * 60), чтобы получить продолжительность в минутах
round
(или floor
) для преобразования дробных минут в целые минуты
- разделить на 60, целое частное - часы, остаток - минуты
abs
функция для получения абсолютного значения (изменить отрицательные значения на положительные)
to_char
формат модели FM00
дает две цифры (ведущие нули)
- используйте функцию
decode
для форматирования знака минус и двоеточия (при необходимости)
Оператор SQL можно было бы сделать менее уродливым, используя функцию PL / SQL, которая принимает два аргумента DATE длительностью в (дробных) днях и возвращает формат hhhh: mi
(непроверено)
create function hhhhmi(an_dur in number)
return varchar2 deterministic
is
begin
if an_dur is null then
return null;
end if;
return decode(sign(an_dur),-1,'-','')
|| to_char(floor(abs(an_dur)*24))
||':'||to_char(mod((abs(an_dur)*1440),60),'FM00');
end;
С определенной функцией:
SELECT hhhhmi(max(EndDate - StartDate)) as MaximumScheduleTime
, hhhhmi(min(EndDate - StartDate)) as MinimumScheduleTime
, hhhhmi(avg(EndDate - StartDate)) as AverageScheduleTime
FROM table1
person
spencer7593
schedule
04.06.2009