В Oracle есть функция, которая вычисляет разницу между двумя датами? - PullRequest
1 голос
/ 04 июня 2009

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

Запрос:

SELECT Round(max((EndDate - StartDate ) * 24), 2) as MaximumScheduleTime,
       Round(min((EndDate - StartDate) * 24), 2)  as MinimumScheduleTime,
       Round(avg((EndDate - StartDate) * 24), 2) as AveragegScheduleTime
FROM table1

Ответы [ 5 ]

10 голосов
/ 04 июня 2009

Вы можете вычесть две даты в Oracle. Результатом является FLOAT, который представляет количество дней между двумя датами. Вы можете выполнить простую арифметику с дробной частью, чтобы вычислить часы, минуты и секунды.

Вот пример:

SELECT TO_DATE('2000/01/02:12:00:00PM', 'yyyy/mm/dd:hh:mi:ssam')-TO_DATE('2000/01/01:12:00:00AM', 'yyyy/mm/dd:hh:mi:ssam') DAYS FROM DUAL

Результат: 1,5

8 голосов
/ 04 июня 2009

Вы можете использовать эти функции:

1) EXTRACT (элемент FROM temporal_value)

2) NUMTOYMINTERVAL (n, ед.)

3) NUMTODSINTERVAL (n, единица измерения).

Например:

SELECT EXTRACT(DAY FROM NUMTODSINTERVAL(end_time - start_time, 'DAY'))
   || ' days ' || 
   EXTRACT(HOUR FROM NUMTODSINTERVAL(end_time - start_time, 'DAY'))
   ||':'|| 
   EXTRACT(MINUTE FROM NUMTODSINTERVAL(end_time - start_time, 'DAY')) 
   ||':'||
   EXTRACT(SECOND FROM NUMTODSINTERVAL(end_time - start_time, 'DAY')) 
   "Lead Time"
FROM table;
4 голосов
/ 04 июня 2009

С Oracle Dates это довольно тривиально, вы можете получить либо ИТОГО (дни, часы, минуты, секунды) между 2 датами просто вычитая их или с небольшим модом вы можете получить дни / часы / минуты / секунды между ними.

http://asktom.oracle.com/tkyte/Misc/DateDiff.html

Также по вышеуказанной ссылке:

Если вы действительно хотите, чтобы "дата" в вашем базы данных, вы можете просто сделать что-то как это:

SQL> create or replace function datediff( p_what in varchar2, 
  2                                       p_d1   in date, 
  3                                       p_d2   in date ) return number 
  4  as 
  5      l_result    number; 
  6  begin 
  7      select (p_d2-p_d1) * 
  8             decode( upper(p_what), 
  9                     'SS', 24*60*60, 'MI', 24*60, 'HH', 24, NULL ) 
 10       into l_result from dual; 
 11 
 11      return l_result; 
 12  end; 
 13  /
Function created
3 голосов
/ 05 июня 2009

Q: В Oracle есть функция, которая вычисляет разницу между двумя датами?

Просто вычтите одно выражение даты из другого, чтобы получить разницу, выраженную в количестве дней. Целая часть - это число целых дней, дробная часть - это доля дня. Простая арифметика после этого умножьте на 24, чтобы получить часы.

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

Это просто вопрос выражения продолжительности в виде целых часов и оставшихся минут.

Мы можем перейти к «старой школе», чтобы получить длительности в формате ччч: ми, используя комбинацию простых встроенных функций:

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
0 голосов
/ 15 мая 2015

Вы можете использовать функцию months_between для преобразования дат в разницу в годах, а затем использовать интересующие вас десятичные годы:

CASE 
WHEN ( ( MONTHS_BETWEEN( TO_DATE(date1, 'YYYYMMDD'), 
                        TO_DATE(date1,'YYYYMMDD'))/12
        )
         BETWEEN Age1DecimalInYears AND Age2DecimalInYears 
      ) 
THEN 'It is between the two dates'
ELSE 'It is not between the two dates' 
END;

Возможно, вам придется изменить формат даты, чтобы он соответствовал заданному формату даты, и убедитесь, что 31-дневный месяц работает для ваших конкретных сценариев.

Ссылка: (найдено на сайте 15.05.2015)
1. Oracle / PLSQL: MONTHS_BETWEEN Функция
2. Справочный центр Oracle - MONTHS_BETWEEN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...