在Oracle中,是否有一个函数可以计算两个日期之间的差异?

时间:2009-06-04 17:58:54

标签: oracle plsql

在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 个答案:

答案 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

答案 1 :(得分:8)

您可以使用以下功能:

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;

答案 2 :(得分:4)

  

使用Oracle Dates,这很漂亮   琐碎的,你可以得到TOTAL   (天,小时,分钟,秒)   仅仅通过减去两个日期之间   他们或你可以用一点mod'ing   得到天/小时/分钟/秒   之间。

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 :(得分:3)

问:在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_expr1date_expr2

让我们解压缩

  • date_expr1 - date_expr2返回天数差异
  • 乘以1440(24 * 60)以获得持续时间(分钟)
  • round(或floor)将小数分钟分解为整数分钟
  • 除以60,整数商是小时,余数是分钟
  • abs函数获取绝对值(将负值更改为正数)
  • to_char格式模型FM00给出两位数(前导零)
  • 使用decode函数格式化负号和冒号(如果需要)

使用PL / SQL函数可以减少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

答案 4 :(得分: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天的月份适用于您的特定方案。

参考文献: (于2015年5月15日在www上找到)
1. Oracle/PLSQL: MONTHS_BETWEEN Function
2. Oracle Help Center - MONTHS_BETWEEN