Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Musisz znaleźć średni czas przetwarzania między wszystkimi rekordami znaczników czasu w Oracle SQL

Wykonywanie interwałów czasowych, a zwłaszcza wykonywanie agregacji (sum, średnich) na wielu interwałach lub grupach interwałowych, nie jest w Oracle proste. Funkcja AVG nie działa w interwałach czasowych, oczekuje liczb. Musimy więc stworzyć własny obiekt agregacji i funkcję, która to zrobi.

Po pierwsze, specyfikacja obiektu :

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
);

I treść obiektu :

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;

Na koniec funkcja który używa powyższego obiektu :

CREATE OR REPLACE FUNCTION avg_interval( x DSINTERVAL_UNCONSTRAINED) 
RETURN DSINTERVAL_UNCONSTRAINED  PARALLEL_ENABLE
AGGREGATE USING AvgInterval;

Teraz możemy z niego korzystać jak to :

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;

Wyjście:

+00 02:00:00.562669

Możemy również agregować na grupy z tym :

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;

Wyjście:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ślad SQL, zdarzenie 10046 w Oracle:trcsess, narzędzie tkprof

  2. Jak sprawdzić, czy plik istnieje w PL/SQL?

  3. Buforowanie Unicode Oracle

  4. Kod intensywnie korzystający z asynchronicznych operacji we/wy działa wolniej niż kod nieasynchroniczny, dlaczego?

  5. Jak wyodrębnić tylko wartość daty z pola daty w Oracle?