甲骨文。将结果传递给自定义函数

时间:2016-06-17 12:08:36

标签: sql oracle plsql

我有一个自定义函数,应该计算上下四分位数。我想以下列方式计算它:

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;

所以它看起来像一个聚合函数。它接收一个数字来计算一个四分数(.25或.75)和一组数字。所以这是函数体:

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;

正如您所看到的,我定义了一种自定义数据类型。这是:

create or replace TYPE NUMBERS_ARRAY AS TABLE OF NUMBER;

但是,它仍然无法正常工作。当我尝试执行时,我收到了这样的错误:

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

据我所知,我对数字集合的定义不正确。我做错了什么?

2 个答案:

答案 0 :(得分:1)

你的功能是期待一个集合,而不是一个简单的数字;因此,您可以使用the COLLECT() function并将生成的内容转换为预期的表类型:

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;

您可能希望调查user-defined aggregate functions作为替代方案。

答案 1 :(得分:0)

我知道我的答案是非正式的。但也许它会帮助你。

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还具有PERCENTILE_DISC,PERCENTILE_CONT分析/聚合功能。