在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 :(得分: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_expr1
和date_expr2
)
让我们解压缩
date_expr1 - date_expr2
返回天数差异round
(或floor
)将小数分钟分解为整数分钟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