sql >> データベース >  >> RDS >> Oracle

OracleSQLのすべてのタイムスタンプレコード間の平均処理時間を見つける必要があります

    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 FUNCTION avg_interval( x DSINTERVAL_UNCONSTRAINED) 
    RETURN DSINTERVAL_UNCONSTRAINED  PARALLEL_ENABLE
    AGGREGATE USING AvgInterval;
    

    これで、使用できるようになりました このように

    with x as (
        select systimestamp - 1/24 as created_date, systimestamp as modified_date from dual
        union
        select systimestamp - 2/24 as created_date, systimestamp as modified_date from dual
        union
        select systimestamp - 3/24 as created_date, systimestamp as modified_date from dual
    )
    select avg_interval(modified_date - created_date)
    from x;
    

    出力:

    +00 02:00:00.562669
    

    グループ全体を集約することもできます これで

    with x as (
        select 'FL' as state, to_dsinterval('0 00:56:30') as duration from dual
        union
        select 'FL' as state, to_dsinterval('0 02:08:40') as duration from dual
        union
        select 'GA' as state, to_dsinterval('0 01:01:00') as duration from dual
    )
    select state, avg_interval(duration)
    from x
    group by state;
    

    出力:

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



    1. Djangoチャンネル入門

    2. SQLServerのSTATISTICSXMLとは何ですか?

    3. ナンバーシリーズジェネレータチャレンジソリューション–パート2

    4. MySQLトリガーの使用