对字符串的“sum”——在Oracle中自定义聚集函数的例子
2006-09-24 17:12
441 查看
[引自] http://blog.itpub.net/post/468/3380
Oracle的定制功能十分强大。前几天在碰到一个问题的时候,查询文档发现,oracle不但允许用户定制自己的函数,还可以定制自己的聚集函数和分析函数。
下面是我使用自定义聚集函数建立一个字符串“sum”的小例子。
SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (
2 STR VARCHAR2(30000),
3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER,
4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,
5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER,
6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER
7 )
8 /
类型已创建。
SQL> CREATE OR REPLACE TYPE BODY T_LINK IS
2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER IS
3 BEGIN
4 SCTX := T_LINK(NULL);
5 RETURN ODCICONST.SUCCESS;
6 END;
7
8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS
9 BEGIN
10 SELF.STR := SELF.STR || VALUE;
11 RETURN ODCICONST.SUCCESS;
12 END;
13
14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER IS
15 BEGIN
16 RETURNVALUE := SELF.STR;
17 RETURN ODCICONST.SUCCESS;
18 END;
19
20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS
21 BEGIN
22 NULL;
23 RETURN ODCICONST.SUCCESS;
24 END;
25 END;
26 /
类型主体已创建。
SQL> CREATE OR REPLACE FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2
2 AGGREGATE USING T_LINK;
3 /
函数已创建。
SQL> CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(20));
表已创建。
SQL> INSERT INTO TEST VALUES (1, 'AAA');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'BBB');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (1, 'ABC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (3, 'CCC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'DDD');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> COL NAME FORMAT A60
SQL> SELECT ID, F_LINK(NAME) NAME FROM TEST GROUP BY ID;
ID NAME
---------- ------------------------------------------------------
1 AAAABC
2 BBBDDD
3 CCC
[引自]http://sunsonbaby.cnblogs.com/archive/2005/01/21/95435.html
另外:
oracle自定义聚集函数接口简介
a. static function ODCIAggregateInitialize(sctx IN OUTstring_agg_type )
return number
自定义聚集函数初始化设置,从这儿开始一个聚集函数
b. member function ODCIAggregateIterate(self IN OUT string_agg_type ,value IN varchar2)
return number
自定义聚集函数,最主要的步骤,这个函数定义我们的聚集函数具体做什么操作,后面的例子,是取最大值,最小值,平均值,还是做连接操作.self 为当前聚集函数的指针,用来与前面的计算结果进行关联
c. member function ODCIAggregateMerge (self IN string_agg_type,returnValue OUT varchar2,flags IN number)
return number
用来合并两个聚集函数的两个不同的指针对应的结果,用户合并不同结果结的数据,特别是处理并行(parallel)查询聚集函数的时候.
d. member function OCDIAggregateTerminate(self IN string_agg_type,returnValue OUT varchar2,flags IN number)
终止聚集函数的处理,返回聚集函数处理的结果.
2. 实现的例子.
3. 具体应用,
字符串聚合
===========================================================
作者: jackywood(http://jackywood.itpub.net)
发表于: 2006.07.01 00:33
分类: 技术探讨
出处: http://jackywood.itpub.net/post/1369/129288 ---------------------------------------------------------------
原贴地址 http://www.itpub.net/477803.html
在put上经常见到有人问"字符串连接"或是"一列多行数据怎么变为一列一行", 在此汇总我所知比较好的几种字符串聚合的方法, 供大家参考.
在这里生成测试数据, 后面详细介绍方法的时候需要用到.
create table tb_agg(
val varchar2(4),
gcol varchar2(4)
)
/
insert into tb_agg
select lpad(rownum,2,'0'), ceil(rownum/5) from dual connect by rownum<=20;
commit;
1. 通过 sys_connect_by_path
需要对数据进行树型构造, 在通过sys_connect_by_path完成字符串的的聚合.
这种方法便于对聚合元素排序, 但是元素与元素间必须要有分割符(如不需要分割符, 需要最后replace掉), 且聚合后的数据不能超过varchar2最大长度的限制.
示例: (该方法中需要用到分析函数来构造树型结构, 并用connect by进行查询)
SQL> with t as (
2 select val, gcol,
3 lag(val) over(partition by gcol order by val) as pval1
4 from tb_agg
5 )
6 select gcol, max(sys_connect_by_path(val, '/')) as aggr
7 from t
8 start with pval1 is null
9 connect by prior val=pval1
10 group by gcol
11 /
GCOL AGGR
-------- ----------------------------------------
1 /01/02/03/04/05
2 /06/07/08/09/10
3 /11/12/13/14/15
4 /16/17/18/19/20
2. 通过自定义聚合函数完成
需要用到oracle提供的自定义聚合函数的方法, 先定义聚合type, 然后定义函数, 来完成字符串的聚合.
这种方法可以任意指定分割符或无分割符, 聚合长度可以通过根据type中定义的不同, 返回varchar2或clob, 因此可以不受varchar2上限限制, 但是对聚合元素排序的话需要特殊处理.
由于自定义聚合函数较长, 请参见 http://www.itpub.net/477803.html
3. 通过自定义集合实现
需要自定义集合类型, 并定义集合聚合函数.
这种方法的特定和自定义聚合函数基本类似.
详细参见: 字符串聚合之自定义集合
-- 注意声明时的长度, 合适的长度最佳, 不要过长, 也不要过小
create or replace type vars is table of varchar2(1000)
/
-- 返回为varchar2, 有 varchar2 大小上限限制的
create or replace function sumvar (p_in in vars) return varchar2
is
v_out varchar2(4000);
begin
for i in 1..p_in.count loop
v_out := v_out || p_in(i);
end loop;
return v_out;
end;
/
-- 返回clob, 无varchar2上限限制
create or replace function sumvarc (p_in in vars) return clob
is
v_out clob;
begin
for i in 1..p_in.count loop
v_out := v_out || p_in(i);
end loop;
return v_out;
end;
/
函数的使用示例:
SQL> select gcol,
2 sumvar(cast(multiset(select '/'||val
3 from tb_agg
4 where a.gcol=gcol
5 order by val) as vars
6 )
7 ) as aggr
8 from tb_agg a
9 group by gcol
10 /
GCOL AGGR
-------- ----------------------------------------
1 /01/02/03/04/05
2 /06/07/08/09/10
3 /11/12/13/14/15
4 /16/17/18/19/20
//------------------------------------------------实际应用--------------------------------------------------------------
CREATE OR REPLACE TYPE "STR_SUM_TYPE" as object (
sum_string varchar2(4000),
str_split varchar(20),
static function ODCIAggregateInitialize(obj_strsum In Out str_sum_type) return number,
member function ODCIAggregateIterate(self In Out str_sum_type,value in varchar2) return number,
member function ODCIAggregateMerge(self In Out str_sum_type,obj_strsum2 In Out str_sum_type) return number,
member function ODCIAggregateTerminate(self In Out str_sum_type,returnValue Out varchar2,flags in number) return number
)
/
CREATE OR REPLACE TYPE BODY str_sum_type is
--初始化
static function ODCIAggregateInitialize(obj_strsum IN OUT str_sum_type) return number
is
begin
obj_strsum := str_sum_type( null,'$SPLIT$' );
return ODCIConst.Success;
end;
--连接
member function ODCIAggregateIterate(self IN OUT str_sum_type,value IN varchar2)
return number
is
begin
self.sum_string := self.sum_string || str_split|| value;
return ODCIConst.Success;
end;
--连接不同聚合的返回
member function ODCIAggregateMerge(self IN OUT str_sum_type,obj_strsum2 IN OUT str_sum_type)
return number
is
begin
self.sum_string := self.sum_string || str_split || obj_strsum2.sum_string;
return ODCIConst.Success;
end;
--最终返回
member function ODCIAggregateTermINate(self IN OUT str_sum_type,returnValue OUT varchar2,flags IN number)
return number
is
begin
returnValue := ltrim(rtrim(self.sum_string,str_split),str_split);
return ODCIConst.Success;
end;
end;
/
------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION f_sums(value varchar2) return varchar2
aggregate using str_sum_type;
/*
自定义聚合函数连接字符串
默认分割符号为$SPLIT$
用法:SELECT SHIP_NO,REPLACE(f_sum(INVOICE_NBR),'$SPLIT$',' ') FROM BILL_FEE GROUP BY SHIP_NO
*/
/
Oracle的定制功能十分强大。前几天在碰到一个问题的时候,查询文档发现,oracle不但允许用户定制自己的函数,还可以定制自己的聚集函数和分析函数。
下面是我使用自定义聚集函数建立一个字符串“sum”的小例子。
SQL> CREATE OR REPLACE TYPE T_LINK AS OBJECT (
2 STR VARCHAR2(30000),
3 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER,
4 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER,
5 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER,
6 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER
7 )
8 /
类型已创建。
SQL> CREATE OR REPLACE TYPE BODY T_LINK IS
2 STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT T_LINK) RETURN NUMBER IS
3 BEGIN
4 SCTX := T_LINK(NULL);
5 RETURN ODCICONST.SUCCESS;
6 END;
7
8 MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT T_LINK, VALUE IN VARCHAR2) RETURN NUMBER IS
9 BEGIN
10 SELF.STR := SELF.STR || VALUE;
11 RETURN ODCICONST.SUCCESS;
12 END;
13
14 MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN T_LINK, RETURNVALUE OUT VARCHAR2, FLAGS IN NUMBE
R) RETURN NUMBER IS
15 BEGIN
16 RETURNVALUE := SELF.STR;
17 RETURN ODCICONST.SUCCESS;
18 END;
19
20 MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT T_LINK, CTX2 IN T_LINK) RETURN NUMBER IS
21 BEGIN
22 NULL;
23 RETURN ODCICONST.SUCCESS;
24 END;
25 END;
26 /
类型主体已创建。
SQL> CREATE OR REPLACE FUNCTION F_LINK(P_STR VARCHAR2) RETURN VARCHAR2
2 AGGREGATE USING T_LINK;
3 /
函数已创建。
SQL> CREATE TABLE TEST (ID NUMBER, NAME VARCHAR2(20));
表已创建。
SQL> INSERT INTO TEST VALUES (1, 'AAA');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'BBB');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (1, 'ABC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (3, 'CCC');
已创建 1 行。
SQL> INSERT INTO TEST VALUES (2, 'DDD');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> COL NAME FORMAT A60
SQL> SELECT ID, F_LINK(NAME) NAME FROM TEST GROUP BY ID;
ID NAME
---------- ------------------------------------------------------
1 AAAABC
2 BBBDDD
3 CCC
[引自]http://sunsonbaby.cnblogs.com/archive/2005/01/21/95435.html
另外:
oracle自定义聚集函数接口简介
a. static function ODCIAggregateInitialize(sctx IN OUTstring_agg_type )
return number
自定义聚集函数初始化设置,从这儿开始一个聚集函数
b. member function ODCIAggregateIterate(self IN OUT string_agg_type ,value IN varchar2)
return number
自定义聚集函数,最主要的步骤,这个函数定义我们的聚集函数具体做什么操作,后面的例子,是取最大值,最小值,平均值,还是做连接操作.self 为当前聚集函数的指针,用来与前面的计算结果进行关联
c. member function ODCIAggregateMerge (self IN string_agg_type,returnValue OUT varchar2,flags IN number)
return number
用来合并两个聚集函数的两个不同的指针对应的结果,用户合并不同结果结的数据,特别是处理并行(parallel)查询聚集函数的时候.
d. member function OCDIAggregateTerminate(self IN string_agg_type,returnValue OUT varchar2,flags IN number)
终止聚集函数的处理,返回聚集函数处理的结果.
2. 实现的例子.
create type strcat_type as object ( cat_string varchar2(4000), static function ODCIAggregateInitialize(cs_ctx In Out strcat_type) return number, member function ODCIAggregateIterate(self In Out strcat_type,value in varchar2) return number, member function ODCIAggregateMerge(self In Out strcat_type,ctx2 In Out strcat_type) return number, member function ODCIAggregateTerminate(self In Out strcat_type,returnValue Out varchar2,flags in number) return number ) / create type body strcat_type is static function ODCIAggregateInitialize(cs_ctx IN OUT strcat_type) return number is begin cs_ctx := strcat_type( null ); return ODCIConst.Success; end; member function ODCIAggregateIterate(self IN OUT strcat_type, value IN varchar2 ) return number is begin self.cat_string := self.cat_string || ','|| value; return ODCIConst.Success; end; member function ODCIAggregateTerminate(self IN Out strcat_type, returnValue OUT varchar2, flags IN number) return number is begin returnValue := ltrim(rtrim(self.cat_string,','),','); return ODCIConst.Success; end; member function ODCIAggregateMerge(self IN OUT strcat_type, ctx2 IN Out strcat_type) return number is begin self.cat_string := self.cat_string || ',' || ctx2.cat_string; return ODCIConst.Success; end; end; / CREATE or replace FUNCTION strcat(input varchar2 ) RETURN varchar2 PARALLEL_ENABLE AGGREGATE USING strcat_type; /
3. 具体应用,
15:16:52 SQL> select empno,ename,deptno,job from scott.emp; EMPNO ENAME DEPTNO JOB ---------- ---------- ---------- --------- 7369 SMITH 20 CLERK 7499 ALLEN 30 SALESMAN 7521 WARD 30 SALESMAN 7566 JONES 20 MANAGER 7654 MARTIN 30 SALESMAN 7698 BLAKE 30 MANAGER 7782 CLARK 10 MANAGER 7788 SCOTT 20 ANALYST 7839 KING 10 PRESIDENT 7844 TURNER 30 SALESMAN 7876 ADAMS 20 CLERK 7900 JAMES 30 CLERK 7902 FORD 20 ANALYST 7934 MILLER 10 CLERK 14 rows selected. Elapsed: 00:00:00.01 15:18:29 SQL> col dept_emplist format a60 15:18:41 SQL> select deptno,strcat(empno||'-'||ename) dept_emplist 15:19:01 2 from scott.emp group by deptno; DEPTNO DEPT_EMPLIST ---------- ------------------------------------------------------------ 10 7782-CLARK,7839-KING,7934-MILLER 20 7369-SMITH,7902-FORD,7876-ADAMS,7788-SCOTT,7566-JONES 30 7499-ALLEN,7698-BLAKE,7654-MARTIN,7844-TURNER,7900-JAMES,7521-WARD Elapsed: 00:00:00.04 15:19:08 SQL> col job_emplist format a80 15:19:23 SQL> select job,strcat(empno||'-'||ename) job_emplist 15:19:43 2 from scott.emp group by job; JOB JOB_EMPLIST --------- -------------------------------------------------------------------------------- ANALYST 7788-SCOTT,7902-FORD CLERK 7369-SMITH,7900-JAMES,7876-ADAMS,7934-MILLER MANAGER 7566-JONES,7782-CLARK,7698-BLAKE PRESIDENT 7839-KING SALESMAN 7499-ALLEN,7521-WARD,7844-TURNER,7654-MARTIN Elapsed: 00:00:00.03 15:19:50 SQL>
字符串聚合
===========================================================
作者: jackywood(http://jackywood.itpub.net)
发表于: 2006.07.01 00:33
分类: 技术探讨
出处: http://jackywood.itpub.net/post/1369/129288 ---------------------------------------------------------------
原贴地址 http://www.itpub.net/477803.html
在put上经常见到有人问"字符串连接"或是"一列多行数据怎么变为一列一行", 在此汇总我所知比较好的几种字符串聚合的方法, 供大家参考.
在这里生成测试数据, 后面详细介绍方法的时候需要用到.
create table tb_agg(
val varchar2(4),
gcol varchar2(4)
)
/
insert into tb_agg
select lpad(rownum,2,'0'), ceil(rownum/5) from dual connect by rownum<=20;
commit;
1. 通过 sys_connect_by_path
需要对数据进行树型构造, 在通过sys_connect_by_path完成字符串的的聚合.
这种方法便于对聚合元素排序, 但是元素与元素间必须要有分割符(如不需要分割符, 需要最后replace掉), 且聚合后的数据不能超过varchar2最大长度的限制.
示例: (该方法中需要用到分析函数来构造树型结构, 并用connect by进行查询)
SQL> with t as (
2 select val, gcol,
3 lag(val) over(partition by gcol order by val) as pval1
4 from tb_agg
5 )
6 select gcol, max(sys_connect_by_path(val, '/')) as aggr
7 from t
8 start with pval1 is null
9 connect by prior val=pval1
10 group by gcol
11 /
GCOL AGGR
-------- ----------------------------------------
1 /01/02/03/04/05
2 /06/07/08/09/10
3 /11/12/13/14/15
4 /16/17/18/19/20
2. 通过自定义聚合函数完成
需要用到oracle提供的自定义聚合函数的方法, 先定义聚合type, 然后定义函数, 来完成字符串的聚合.
这种方法可以任意指定分割符或无分割符, 聚合长度可以通过根据type中定义的不同, 返回varchar2或clob, 因此可以不受varchar2上限限制, 但是对聚合元素排序的话需要特殊处理.
由于自定义聚合函数较长, 请参见 http://www.itpub.net/477803.html
3. 通过自定义集合实现
需要自定义集合类型, 并定义集合聚合函数.
这种方法的特定和自定义聚合函数基本类似.
详细参见: 字符串聚合之自定义集合
-- 注意声明时的长度, 合适的长度最佳, 不要过长, 也不要过小
create or replace type vars is table of varchar2(1000)
/
-- 返回为varchar2, 有 varchar2 大小上限限制的
create or replace function sumvar (p_in in vars) return varchar2
is
v_out varchar2(4000);
begin
for i in 1..p_in.count loop
v_out := v_out || p_in(i);
end loop;
return v_out;
end;
/
-- 返回clob, 无varchar2上限限制
create or replace function sumvarc (p_in in vars) return clob
is
v_out clob;
begin
for i in 1..p_in.count loop
v_out := v_out || p_in(i);
end loop;
return v_out;
end;
/
函数的使用示例:
SQL> select gcol,
2 sumvar(cast(multiset(select '/'||val
3 from tb_agg
4 where a.gcol=gcol
5 order by val) as vars
6 )
7 ) as aggr
8 from tb_agg a
9 group by gcol
10 /
GCOL AGGR
-------- ----------------------------------------
1 /01/02/03/04/05
2 /06/07/08/09/10
3 /11/12/13/14/15
4 /16/17/18/19/20
//------------------------------------------------实际应用--------------------------------------------------------------
CREATE OR REPLACE TYPE "STR_SUM_TYPE" as object (
sum_string varchar2(4000),
str_split varchar(20),
static function ODCIAggregateInitialize(obj_strsum In Out str_sum_type) return number,
member function ODCIAggregateIterate(self In Out str_sum_type,value in varchar2) return number,
member function ODCIAggregateMerge(self In Out str_sum_type,obj_strsum2 In Out str_sum_type) return number,
member function ODCIAggregateTerminate(self In Out str_sum_type,returnValue Out varchar2,flags in number) return number
)
/
CREATE OR REPLACE TYPE BODY str_sum_type is
--初始化
static function ODCIAggregateInitialize(obj_strsum IN OUT str_sum_type) return number
is
begin
obj_strsum := str_sum_type( null,'$SPLIT$' );
return ODCIConst.Success;
end;
--连接
member function ODCIAggregateIterate(self IN OUT str_sum_type,value IN varchar2)
return number
is
begin
self.sum_string := self.sum_string || str_split|| value;
return ODCIConst.Success;
end;
--连接不同聚合的返回
member function ODCIAggregateMerge(self IN OUT str_sum_type,obj_strsum2 IN OUT str_sum_type)
return number
is
begin
self.sum_string := self.sum_string || str_split || obj_strsum2.sum_string;
return ODCIConst.Success;
end;
--最终返回
member function ODCIAggregateTermINate(self IN OUT str_sum_type,returnValue OUT varchar2,flags IN number)
return number
is
begin
returnValue := ltrim(rtrim(self.sum_string,str_split),str_split);
return ODCIConst.Success;
end;
end;
/
------------------------------------------------------------------------------------------------
CREATE OR REPLACE FUNCTION f_sums(value varchar2) return varchar2
aggregate using str_sum_type;
/*
自定义聚合函数连接字符串
默认分割符号为$SPLIT$
用法:SELECT SHIP_NO,REPLACE(f_sum(INVOICE_NBR),'$SPLIT$',' ') FROM BILL_FEE GROUP BY SHIP_NO
*/
/
相关文章推荐
- 对字符串的“sum”——在Oracle中自定义聚集函数的例子
- 对字符串的“sum”——在Oracle中自定义聚集函数的例子
- 对字符串的“sum”——在Oracle中自定义聚集函数的例子
- 对字符串的“sum”——在Oracle中自定义聚集函数的例子
- 一个Oracle自定义聚集函数的例子
- 自定义Oracle聚集函数:模拟SUM,MAX,AVG
- 关于oracle9以上自定义聚集函数的例子
- [收藏]在oracle里定义一个自定义字符串的聚集函数
- Oracle解析json字符串 获取指定值自定义函数代码
- Oracle自定义聚集函数
- Oracle自定义的聚集函数的强大功能
- Oracle中将查询的结果放入一张自定义表中的例子
- Oracle自定义聚集函数
- oracle自定义聚集函数实现列合并
- oracle中sum字符串方法
- Oracle自定义聚合函数实现字符串连接的聚合
- oracle过滤分割字符串自定义函数
- 用Oracle自定义聚合函数实现字符串连接的聚合
- Oracle自定义聚集函数
- 自定义oracle聚集函数,类似于功能wm_concat