2009-06-04 3 views
1

В Oracle есть функция, которая вычисляет разницу между двумя датами? Если нет, это способ показать разницу между двумя датами в часах и минутах?В 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 
+0

Вы нашли ответ, который вы искали? –

ответ

4

С Oracle Даты, это довольно тривиально, вы можете получить либо СУММА (дни, часы, минуты, секунды) между 2 даты просто путем вычитания их или с небольшим mod'ing вы можете получить дни/часы/минуты/секунды между.

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

Кроме того, из приведенной выше ссылке:

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

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 
+0

Пожалуйста, укажите, что такое p_what, используемое для – Donny

8

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

1) ЭКСТРАКТ (элемент ОТ temporal_value)

2) NUMTOYMINTERVAL (п, модуль)

3) NUMTODSINTERVAL (п, единица).

Например:

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; 
+0

ПРИМЕЧАНИЕ. Это решение не сообщает часы продолжительностью> 24 часа. То есть, если разница между end_time и start_time превышает 24 часа, это возвращает истекшие часы, за исключением любых 24-часовых периодов. – spencer7593

+0

привет Спенсер, спасибо, что указал. Я отредактировал решение. –

10

Вы можете вычесть две даты в 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

3

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

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

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

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

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

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 

Да, это Fugly, но это довольно быстро. Вот простой случай, который показывает лучше, что происходит:

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 длительность в (дробных) дней и возвращает отформатированный РРРР: ми

(непроверенных)

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

Вы можете использовать функцию 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 день месяца работы для конкретных сценариев.

Ссылки: (найдено на WWW на 05/15/2015)
1. Oracle/PLSQL: MONTHS_BETWEEN Function
2. Oracle Help Center - MONTHS_BETWEEN

Смежные вопросы