需要查找Oracle SQL中所有时间戳记录之间的平均处理时间

需要查找Oracle SQL中所有时间戳记录之间的平均处理时间,sql,oracle,Sql,Oracle,我是SQL/Oracle方面的新手,遇到了两个需要整合的问题: 1.)查找处理一条记录所需的时间(以天为单位,HH:MM:SS),然后 2.)根据所选结果的所有TimesAdmins查找平均处理时间 我解决了第一个问题(也许不是最好的方法),剩下的第二个问题让我头疼。我会尝试用数据来解释 因此,为了解决第1个问题,我编写了下面的查询,它生成了许多结果,其中的一个摘录显示在查询下面 SELECT to_number( to_char(to_date('1','J') + (t_modified -

我是SQL/Oracle方面的新手,遇到了两个需要整合的问题:

1.)查找处理一条记录所需的时间(以天为单位,HH:MM:SS),然后 2.)根据所选结果的所有TimesAdmins查找平均处理时间

我解决了第一个问题(也许不是最好的方法),剩下的第二个问题让我头疼。我会尝试用数据来解释

因此,为了解决第1个问题,我编写了下面的查询,它生成了许多结果,其中的一个摘录显示在查询下面

SELECT to_number( to_char(to_date('1','J') + (t_modified - (t_created - (0/24))), 'J') - 1)  days,
to_char(to_date('00:00:00','HH24:MI:SS') +   
(t_modified - (t_created - (0/24))), 'HH24:MI:SS') TimeInQueue, message_no, id, t_created, t_modified
from TABLE   
where message_no in (MESSAGENUMBER) and status = 1 and t_modified > sysdate-2 order by t_created;
此查询产生以下结果: 我是论坛新手,因此无法在问题中发布图片,因此这里有一个链接:

现在,我真正被困的地方是。。。在T_MODIFIED字段中,对于给定的时间跨度(比如sysdate-1),我需要找到所有记录的T_修改值之间的平均值。因此,这里的最终目标是找到在整个选定范围内(sysdate-1、-2或您所拥有的任何内容)处理这些记录所需的平均时间。所以我需要把所有1月8日的日期都放在T_MODIFIED列中,找出它们之间的平均时间。我真的希望这是有意义的。如果有任何问题,我会尽量详细说明


谢谢

在Oracle中,执行时间间隔,尤其是跨多个时间间隔或时间间隔组进行聚合(求和、平均值)并不简单。AVG函数不适用于时间戳间隔,它需要数字。因此,我们需要创建自己的聚合对象和函数来实现这一点

首先,对象规范:

CREATE OR REPLACE TYPE AvgInterval 
AS OBJECT (
runningSum INTERVAL DAY(9) TO SECOND(9),
runningCnt number,

STATIC FUNCTION ODCIAggregateInitialize
  ( actx IN OUT AvgInterval
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateIterate
  ( self  IN OUT AvgInterval,
    val   IN       DSINTERVAL_UNCONSTRAINED
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateTerminate
  ( self             IN   AvgInterval,
    returnValue  OUT DSINTERVAL_UNCONSTRAINED,
    flags           IN   NUMBER
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateMerge
  (self  IN OUT AvgInterval,
   ctx2 IN      AvgInterval
  ) RETURN NUMBER
);
CREATE OR REPLACE TYPE BODY AvgInterval AS
STATIC FUNCTION ODCIAggregateInitialize
  ( actx IN OUT AvgInterval
  ) RETURN NUMBER IS 
  BEGIN
    IF actx IS NULL THEN
      actx := AvgInterval (INTERVAL '0 0:0:0.0' DAY TO SECOND, 0);
    ELSE
      actx.runningSum := INTERVAL '0 0:0:0.0' DAY TO SECOND;
      actx.runningCnt := 0;
    END IF;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateIterate
  ( self  IN OUT AvgInterval,
    val   IN     DSINTERVAL_UNCONSTRAINED
  ) RETURN NUMBER IS
  BEGIN
    self.runningSum := self.runningSum + val;
    self.runningCnt := self.runningCnt + 1;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateTerminate
  ( self        IN  AvgInterval,
    ReturnValue OUT DSINTERVAL_UNCONSTRAINED,
    flags       IN  NUMBER
  ) RETURN NUMBER IS
  BEGIN
    if (runningCnt <> 0) then
        returnValue := (self.runningSum/runningCnt);
    else
        returnValue := self.runningSum;
    end if;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateMerge
  (self IN OUT AvgInterval,
   ctx2 IN     AvgInterval
  ) RETURN NUMBER IS
  BEGIN
    self.runningSum := self.runningSum + ctx2.runningSum;
    self.runningCnt := self.runningCnt + ctx2.runningCnt;
    RETURN ODCIConst.Success;
  END;

END;
以及对象体

CREATE OR REPLACE TYPE AvgInterval 
AS OBJECT (
runningSum INTERVAL DAY(9) TO SECOND(9),
runningCnt number,

STATIC FUNCTION ODCIAggregateInitialize
  ( actx IN OUT AvgInterval
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateIterate
  ( self  IN OUT AvgInterval,
    val   IN       DSINTERVAL_UNCONSTRAINED
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateTerminate
  ( self             IN   AvgInterval,
    returnValue  OUT DSINTERVAL_UNCONSTRAINED,
    flags           IN   NUMBER
  ) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateMerge
  (self  IN OUT AvgInterval,
   ctx2 IN      AvgInterval
  ) RETURN NUMBER
);
CREATE OR REPLACE TYPE BODY AvgInterval AS
STATIC FUNCTION ODCIAggregateInitialize
  ( actx IN OUT AvgInterval
  ) RETURN NUMBER IS 
  BEGIN
    IF actx IS NULL THEN
      actx := AvgInterval (INTERVAL '0 0:0:0.0' DAY TO SECOND, 0);
    ELSE
      actx.runningSum := INTERVAL '0 0:0:0.0' DAY TO SECOND;
      actx.runningCnt := 0;
    END IF;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateIterate
  ( self  IN OUT AvgInterval,
    val   IN     DSINTERVAL_UNCONSTRAINED
  ) RETURN NUMBER IS
  BEGIN
    self.runningSum := self.runningSum + val;
    self.runningCnt := self.runningCnt + 1;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateTerminate
  ( self        IN  AvgInterval,
    ReturnValue OUT DSINTERVAL_UNCONSTRAINED,
    flags       IN  NUMBER
  ) RETURN NUMBER IS
  BEGIN
    if (runningCnt <> 0) then
        returnValue := (self.runningSum/runningCnt);
    else
        returnValue := self.runningSum;
    end if;
    RETURN ODCIConst.Success;
  END;

MEMBER FUNCTION ODCIAggregateMerge
  (self IN OUT AvgInterval,
   ctx2 IN     AvgInterval
  ) RETURN NUMBER IS
  BEGIN
    self.runningSum := self.runningSum + ctx2.runningSum;
    self.runningCnt := self.runningCnt + ctx2.runningCnt;
    RETURN ODCIConst.Success;
  END;

END;
现在,我们可以像这样使用它:

输出:

+00 02:00:00.562669
FL  +00 01:32:35.000000
GA  +00 01:01:00.000000
我们还可以通过以下方法对组进行聚合:

输出:

+00 02:00:00.562669
FL  +00 01:32:35.000000
GA  +00 01:01:00.000000

请发布模式和示例数据,显示所需的结果集。哇。。。我没料到会有这么大的成就。在我理解之前,我必须用谷歌搜索你回复中的几乎每个词。我不想使用它,直到我知道它是如何工作的。。。我们应该学到很多。当我能够测试出来时,我会回复。任何智慧的话语,只要能解释这到底在做什么,都将是伟大的!非常感谢。很抱歉,这看起来很难理解,但这是在Oracle中创建自定义聚合函数的一个相当标准的模板。在Oracle中减去2个时间戳,就得到了一个时间间隔(与减去2个日期得到一个数字相反)。不幸的是,AVG函数不能在时间间隔上工作,所以我创建了一个自定义函数,教Oracle如何工作。它基本上保持了一个运行的时间间隔总和和一个运行的时间间隔计数(参见odciaggregateiteite)。处理所有数据时,它计算平均值(ODCIAggregateTerminate)。