Oracle sqlSubtract两个日期之间

时间:2012-03-20 19:12:15

标签: oracle

我需要帮助来编写查询,请执行以下操作: 在两列之间减去(开始日期和结束日期),请注意列的类型为 char 而非日期,这是确切的格式: 10 -MAR-12 11.11.40.288389000 AM ),然后得到结果的平均值。

2 个答案:

答案 0 :(得分:1)

我认为这是作业,所以有些提示......

首先不要将日期存储为varchar,这会导致您和优化者出现各种问题。

其次,Oracle的date数据类型只能存储到第二个精度,而你的字符串只有一秒的分数,所以你看的是timestamp而不是date。您可以使用to_timestamp()函数将字符串转换为时间戳,并传递合适的format mask。哦,好吧,我感觉很慷慨:

select to_timestamp(start_date, 'DD-Mon-RR HH.MI.SS.FF9 AM') from your_table;

第三,减去两个时间戳将为您提供interval数据类型,您需要从中以可读格式提取所需的信息。搜索此网站或其他地方的时间戳减法,但我会以this recent one为样本点。

平均值有点棘手,因此您可能希望将间隔转换为数字;再次搜索以前的问题,例如this one。间隔的大小,您实际关注的精度以及您希望输出格式化的方式等将对您要采用的方法产生一些影响。


如果你需要一个近似的结果,那么@Joachim Isaksson的回答会给你 - '近似'因为四舍五入;例如,小于一秒的持续时间将显示为零。使用时间戳转换为日期可以看到相同的效果,这也会丢失小数秒:

select 24*60*60*avg(
    cast(to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
        - cast(to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as date)
    ) as avg_duration
from process_audit;

通过提取时间戳的各个组成部分可以找到更准确的答案,就像我之前链接的问题一样。如果你知道你的持续时间总是少于一个小时,你可能不需要它们,但是如果你需要不止一个(即如果持续时间可能超过一分钟)那么使用中间公用表表达式简化了事情a位:

with cte as (
    select to_timestamp(step_ending_time, 'DD-Mon-RR HH.MI.SS.FF9 AM')
        - to_timestamp(step_starting_time, 'DD-Mon-RR HH.MI.SS.FF9 AM') as duration
    from process_audit
)
select avg(extract(second from duration)
    + extract(minute from duration) * 60
    + extract(hour from duration) * 60 * 60
    + extract(day from duration) * 60 * 60 * 24) as avg_duration
from cte;

有两个样本行,一个间隔恰好为一秒,另一个恰好为1.5秒,这样会得到结果1.25

答案 1 :(得分:0)

关于在VARCHAR中存储时间的评论;甲骨文的to_date来救援;这应该可以帮助您显示时间之间的平均秒数。由于你对精度的细节有点低,所以我并没有打扰“子秒”;

SELECT 24*3600*AVG(
  to_date(enddate,   'DD-Mon-YY HH.Mi.SS.????????? AM') -
  to_date(startdate, 'DD-Mon-YY HH.Mi.SS.????????? AM')) avg_seconds
FROM TableA;

演示here