如何平均时间间隔?

Jus*_*alt 15 sql oracle timestamp ora-00932

在Oracle 10g中,我有一个表,其中包含时间戳,显示某些操作需要多长时间.它有两个时间戳字段:starttime和endtime.我想找到这些时间戳给出的持续时间的平均值.我尝试:

select avg(endtime-starttime) from timings;
Run Code Online (Sandbox Code Playgroud)

但得到:

SQL错误:ORA-00932:不一致的数据类型:预期NUMBER获得INTERVAL DAY TO SECOND

这有效:

select
     avg(extract( second from  endtime - starttime) +
        extract ( minute from  endtime - starttime) * 60 +
        extract ( hour   from  endtime - starttime) * 3600) from timings;
Run Code Online (Sandbox Code Playgroud)

但是真的很慢.

有没有更好的方法将间隔转换为秒数,或者其他方式做到这一点?

编辑:真正放慢这一点的是我在开始时间之前有一些终结时间.由于某些原因,这个计算非常缓慢.我的基本问题是通过从查询集中删除它们来解决的.我还定义了一个函数来更容易地进行这种转换:

FUNCTION fn_interval_to_sec ( i IN INTERVAL DAY TO SECOND )
RETURN NUMBER
IS
  numSecs NUMBER;
BEGIN
  numSecs := ((extract(day from i) * 24
         + extract(hour from i) )*60
         + extract(minute from i) )*60
         + extract(second from i);
  RETURN numSecs;
END;
Run Code Online (Sandbox Code Playgroud)

Vad*_*zim 21

在Oracle中,有一种更短,更快,更好的方式可以在几秒钟内获得DATETIME差异,而不是使用多个提取的毛茸茸公式.

试试这个以秒为单位获得响应时间:

(sysdate + (endtime - starttime)*24*60*60 - sysdate)
Run Code Online (Sandbox Code Playgroud)

在减去TIMESTAMP时,它还会保留小数部分秒.

有关详细信息,请参见http://kennethxu.blogspot.com/2009/04/converting-oracle-interval-data-type-to.html.


请注意,自定义pl/sql函数具有显着的性能开销,可能不适合繁重的查询.


jim*_*orr 9

如果您的结束时间和开始时间不在彼此的一秒之内,您可以将时间戳作为日期投射并进行日期算术:

select avg(cast(endtime as date)-cast(starttime as date))*24*60*60 
  from timings;
Run Code Online (Sandbox Code Playgroud)


Chr*_*lly 7

最干净的方法是编写自己的聚合函数来执行此操作,因为它将以最干净的方式处理它(处理亚秒级分辨率等).

事实上,这个问题曾经在asktom.oracle.com上被问及(并回答)了一段时间(文章包含源代码).


Ada*_*ire 2

Oracle 中似乎没有任何函数可以对INTERVAL DAY TO SECONDto进行显式转换NUMBER请参阅本文档末尾的表格,这意味着不存在此类转换。

其他来源似乎表明您正在使用的方法是从INTERVAL DAY TO SECOND数据类型获取数字的唯一方法。

在这种特殊情况下,您可以尝试的唯一另一件事是在减去它们之前转换为数字,但由于这会产生两倍的extract离子,因此可能会更慢:

select
     avg(
       (extract( second from endtime)  +
        extract ( minute from endtime) * 60 +
        extract ( hour   from  endtime ) * 3600) - 
       (extract( second from starttime)  +
        extract ( minute from starttime) * 60 +
        extract ( hour   from  starttime ) * 3600)
      ) from timings;
Run Code Online (Sandbox Code Playgroud)