如何计算存储为字符串的平均次数?

时间:2016-04-11 16:02:15

标签: sql string oracle average

我的表包含存储为字符串的时间:

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:无效号码”。

如何计算这些时间值的平均值?

1 个答案:

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

哪个更准确,但您必须再次提取元素才能获得字符串。