2016-06-17 15 views
0

Ich habe eine benutzerdefinierte Funktion, die obere und untere Quartile berechnen soll. Ich möchte es auf folgende Weise berechnen:Oracle. Übergeben Sie das Ergebnis an die benutzerdefinierte Funktion

SELECT QUARTILE_UTILS.GET_QUARTILE(0.25, YEAR_1_FTE), 
     QUARTILE_UTILS.GET_QUARTILE(0.75, YEAR_1_FTE) 
FROM SOME_TABLE WHERE FIRM_ID=999; 

So sieht es wie eine Aggregatfunktion aus. Es erhält eine Zahl, um ein Viertel (.25 oder .75) und eine Sammlung von Zahlen zu berechnen. Also hier ist die Funktion Körper:

create or replace PACKAGE BODY QUARTILE_UTILS AS 
    FUNCTION GET_QUARTILE(PERCENTILE NUMBER, DATASET NUMBERS_ARRAY) RETURN NUMBER 
    IS 
    REMINDER NUMBER := 0; 
    I SIMPLE_INTEGER := 0; 
    RESULT NUMBER := 0; 
    BEGIN 
    .... 
    RETURN RESULT; 
    END; 
END QUARTILE_UTILS; 

Und wie Sie sehen können, habe ich einen benutzerdefinierten Datentyp definiert. Hier ist es:

create or replace TYPE NUMBERS_ARRAY AS TABLE OF NUMBER; 

Allerdings funktioniert es immer noch nicht. Wenn ich auszuführen versuche ich solche Fehler erhalten:

PLS-306: wrong number or types of arguments in call to 'GET_QUARTILE' 

Was, wie ich meine Definition von Sammlung von Nummer verstehen falsch ist. Was mache ich falsch?

+0

Welcher Datentyp ist YEAR_1_FTE? Vermutlich kein geschachtelter Tabellentyp. Sie möchten über alle Werte aus der Tabelle aggregieren - denke ich -, also versuchen Sie [eine benutzerdefinierte Aggregatfunktion] zu schreiben (http://docs.oracle.com/cd/E11882_01/appdev.112/e10765/ aggr_functions.htm)? Oder möchten Sie die Werte aus der Tabelle in eine Sammlung umwandeln und diese an Ihre aktuelle Funktion übergeben? –

+0

@AlexPoole YEAR_1_FTE ist nur eine Nummer. Also ja, ich muss nur eine Sammlung von Zahlen übergeben. –

Antwort

1

Ihre Funktion erwartet eine Sammlung, keine einfache Zahl; so können Sie the COLLECT() function und werfen verwenden, was das für den erwarteten Tabellentyp erzeugt:

SELECT QUARTILE_UTILS.GET_QUARTILE(0.25, CAST(COLLECT(YEAR_1_FTE) AS NUMBERS_ARRAY)), 
     QUARTILE_UTILS.GET_QUARTILE(0.75, CAST(COLLECT(YEAR_1_FTE) AS NUMBERS_ARRAY)) 
FROM SOME_TABLE WHERE FIRM_ID=999; 

Sie könnten allerdings user-defined aggregate functions als Alternative untersuchen wollen.

+0

Vielen Dank für Ihre Antwort. Ich habe diesen Artikel über benutzerdefinierte Aggregatfunktionen gesehen. Ich sah, dass ich einen benutzerdefinierten Datentyp entwickeln sollte. Für mich sieht es einfach wierdig aus, dass ich all diese Schritte ausführen soll, nur um ein Array von ganzen Zahlen zu übergeben. –

+0

Sie müssen ein Array von ganzen Zahlen aus den einzelnen Zahlen in jeder Zeile erstellen. Das scheint nicht unangemessen. –

0

Ich weiß, dass meine Antwort offtopic ist. Aber vielleicht hilft es dir.

with abc as (select 1 lp from dual 
       union all 
       select 2 from dual 
       union all 
       select 4 from dual 
       union all 
       select 5 from dual 
       union all 
       select 8 from dual 
       union all 
       select 9 from dual 
       union all 
       select 10 from dual 
       union all 
      select 12 from dual) 
select median(case when quartiles =1 then lp else null end), /* .25 */ 
     median(case when quartiles =3 then lp else null end) /* .75 */ 
from 
( 
select 
     lp, ntile(4) over(order by lp) quartiles 
from abc 
) 

Oracle hat auch PERCENTILE_DISC,PERCENTILE_CONT analytische/Aggregation-Funktion.

Verwandte Themen