我认为这是家庭作业,所以一些提示...
首先不要将日期存储为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;
可以通过提取时间戳的各个组成部分来找到更准确的答案,就像我之前链接的一个问题一样。如果你知道你的持续时间总是少于一个小时,你可能不需要它们,但是如果你需要一个以上(即如果持续时间可能超过一分钟),那么使用中间公用表表达式可以简化事情位:
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 秒,一个间隔正好是 1.5 秒,这给出了结果 1.25。