我的表包含存储为字符串的时间:
select s.average from Tabela s;
AVERAGE
--------
1:26:27
0:10:03
0:10:04
0:10:15
0:09:40
0:09:32
0:09:55
我需要获得那些时间的平均值。我试着用:
select avg(to_char(to_timestamp(s.average,'hh24:mi:ss'))) from Tabela s
但我不能那样使用avg()
;它得到“ORA-01722:无效号码”。
如何计算这些时间值的平均值?
答案 0 :(得分:0)
您将字符串转换为时间戳,然后返回字符串,然后尝试对其进行平均。无论如何,你无法平均时间戳值。
您可以将每个字符串转换为名义日期的时间,并从固定日期(例如方便日期)获取偏移量,这将是包含小数部分的天数:
select average,
to_date(average, 'HH24:MI:SS') as dt,
to_date(average, 'HH24:MI:SS') - date '1970-01-01' as dt_diff
from tabela;
AVERAGE DT DT_DIFF
------- ------------------- -------------
1:26:27 2016-04-01 01:26:27 16892.06003
0:10:03 2016-04-01 00:10:03 16892.00698
0:10:04 2016-04-01 00:10:04 16892.00699
0:10:15 2016-04-01 00:10:15 16892.00712
0:09:40 2016-04-01 00:09:40 16892.00671
0:09:32 2016-04-01 00:09:32 16892.00662
0:09:55 2016-04-01 00:09:55 16892.00689
然后,您可以平均该天数差异,并将其添加回相同的固定日期,最后将时间部分提取为字符串:
select avg(to_date(average, 'HH24:MI:SS') - date '1970-01-01') as avg_dt_diff,
to_char(date '1970-01-01' + avg(to_date(average, 'HH24:MI:SS') - date '1970-01-01'),
'HH24:MI:SS') as result
from tabela;
AVG_DT_DIFF RESULT
------------- --------
16892.01448 00:20:51
仅当字符串全部小于24小时时才会起作用;如果超过该值,to_date()
将会失败。
您也可以间隔进行,但使用它们会更加困难:
select average, to_dsinterval('0 ' || average) as avg_int
from tabela;
AVERAGE AVG_INT
------- -----------
1:26:27 0 1:26:27.0
0:10:03 0 0:10:3.0
0:10:04 0 0:10:4.0
0:10:15 0 0:10:15.0
0:09:40 0 0:9:40.0
0:09:32 0 0:9:32.0
0:09:55 0 0:9:55.0
然后提取秒数并转换为另一个间隔:
select numtodsinterval(avg((extract(hour from avg_int) * 60 * 60)
+ (extract(minute from avg_int) * 60)
+ extract(second from avg_int)), 'SECOND') as result
from (
select to_dsinterval('0 ' || average) as avg_int
from tabela
);
RESULT
-------------------
0 0:20:50.857142857
哪个更准确,但您必须再次提取元素才能获得字符串。