gpt4 book ai didi

oracle - Oracle 的用户定义聚合函数可以定义为用于两列吗?

转载 作者:行者123 更新时间:2023-12-04 22:45:00 27 4
gpt4 key购买 nike

我想实现一个自定义的回归聚合函数,类似于现有的 REGR_SLOPE .

我要定义的函数需要获取两列作为参数,例如

select 
T.EMPLOYEE_ID,
CUSTOM_REGR_SLOPE(T.DATE, T.SALARY) as SALARY_TREND
from (...) T
group by T.EMPLOYEE_ID;

Oracle 的文档表明这可能是不可能的,但我可能不擅长在字里行间阅读 ;-) 。

我们使用 Oracle 12。

最佳答案

是的,如果您真的想要/需要,这是可能的。你可以这样做:

首先,创建一个对象类型:

create or replace type two_nums_t as object
(
num1 number,
num2 number
);

然后创建您的自定义规范:
CREATE OR REPLACE TYPE TotalSumPair
AS OBJECT (
runningSum1 number,
runningCnt1 number,
runningSum2 number,
runningCnt2 number,

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

MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT TotalSumPair,
val IN two_nums_t
) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateTerminate
( self IN TotalSumPair,
returnValue OUT NUMBER, -- return
flags IN NUMBER
) RETURN NUMBER,

MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT TotalSumPair,
ctx2 IN TotalSumPair
) RETURN NUMBER
);

和自定义 body :
CREATE OR REPLACE TYPE BODY TotalSumPair AS
STATIC FUNCTION ODCIAggregateInitialize
( actx IN OUT TotalSumPair
) RETURN NUMBER IS
BEGIN
IF actx IS NULL THEN
actx := TotalSumPair(0,0,0,0);
ELSE
actx.runningSum1 := 0;
actx.runningCnt1 := 0;
actx.runningSum2 := 0;
actx.runningCnt2 := 0;
END IF;
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateIterate
( self IN OUT TotalSumPair,
val IN two_nums_t
) RETURN NUMBER IS
BEGIN
self.runningSum1 := self.runningSum1 + nvl(val.num1,0);
self.runningSum2 := self.runningSum2 + nvl(val.num2,0);
self.runningCnt1 := self.runningCnt1 + 1;
self.runningCnt2 := self.runningCnt2 + 1;
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateTerminate
( self IN TotalSumPair,
ReturnValue OUT NUMBER,
flags IN NUMBER
) RETURN NUMBER IS
BEGIN
--if (runningCnt1 <> 0) then
returnValue := (self.runningSum1 + self.runningSum2);
--else
-- returnValue := self.runningSum1;
--end if;
RETURN ODCIConst.Success;
END;

MEMBER FUNCTION ODCIAggregateMerge
(self IN OUT TotalSumPair,
ctx2 IN TotalSumPair
) RETURN NUMBER IS
BEGIN
self.runningSum1 := self.runningSum1 + ctx2.runningSum1;
self.runningCnt1 := self.runningCnt1 + ctx2.runningCnt1;
self.runningSum2 := self.runningSum2 + ctx2.runningSum2;
self.runningCnt2 := self.runningCnt2 + ctx2.runningCnt2;
RETURN ODCIConst.Success;
END;

END;

定义你的函数:
CREATE OR REPLACE FUNCTION total_sum_pair( x two_nums_t) 
RETURN number PARALLEL_ENABLE
AGGREGATE USING TotalSumPair;

现在这样称呼它:
with x as (
select 'X' as id, 1 as num1, 2 as num2 from dual
union all
select 'X' as id, 3 as num1, 4 as num2 from dual
union all
select 'Z' as id, 5 as num1, 6 as num2 from dual
)
select id, total_sum_pair(two_nums_t(num1, num2)) sum
from x
group by id;

输出:
ID  SUM
X 10
Z 11

这将每个 X 行 (1+2+3+4) 和每个 Y 行 (5+6) 的两个数字相加。

呼! ;)

关于oracle - Oracle 的用户定义聚合函数可以定义为用于两列吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31434721/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com