数据库中分组字符串相加<br>SQL> select * from test;<br><br>ID MC<br>---------- -------------<br>1 11111<br>1 22222<br>2 11111<br>2 22222<br>3 11111<br>3 22222<br>3 33333<br><br>已选择7行。<br><br>SQL> select id,ltrim(max(sys_connect_by_path(mc,',')),',') row2col<br>from (select id,mc,<br>id+(row_number() over(order by id)) node_id,<br>row_number() over(partition by id order by id) rn<br>from test)<br>start with rn = 1<br>connect by node_id-1 = prior node_id<br>group by id<br>order by id;<br><br>ID ROW2COL<br>---------- -------------------------------------------------------------<br>1 11111,22222<br>2 11111,22222<br>3 11111,22222,33333<br><br>SQL> select id,replace(max(sys_connect_by_path(mc,',')),',') row2col<br>from (select id,mc,<br>id+(row_number() over(order by id)) node_id,<br>row_number() over(partition by id order by id) rn<br>from test)<br>start with rn = 1<br>connect by node_id-1 = prior node_id<br>group by id<br>order by id;<br><br>ID ROW2COL<br>---------- ------------------------------------------------------------<br>1 1111122222<br>2 1111122222<br>3 111112222233333<br><br><br><br><br>--该测试脚本可以直接运行<br><br>--现在想把数据库中数据按照固定字段分组相加,这里总结了三种方法。<br><br>--创建测试表、添加测试数据<br><br>create table test(id varchar2(10),mc varchar2(50));<br>insert into test values('1','11111');<br>insert into test values('1','22222');<br>insert into test values('2','11111');<br>insert into test values('2','22222');<br>insert into test values('3','11111');<br>insert into test values('3','22222');<br>insert into test values('3','33333');<br>commit;<br><br>--方法一:<br><br><br>set serveroutput on size 1000000 <br>declare <br>union_mc varchar2(200); <br>begin <br>for cur_a in(select distinct id from test) loop <br>for cur_b in(select mc from test where id=cur_a.id) loop <br>union_mc:=union_mc||cur_b.mc; <br>end loop; <br>dbms_output.put_line(cur_a.id||chr(9)||union_mc); <br>union_mc := ''; <br>end loop; <br>end; <br>/ <br><br>--方法二:<br><br>CREATE OR REPLACE function link(v_id varchar2) <br>return varchar2 <br>is <br>union_mc varchar2(200); <br>begin <br>for cur in (select mc from test where id=v_id) loop <br>union_mc := union_mc||cur.mc; <br>end loop; <br>union_mc := rtrim(union_mc,1); <br>return union_mc; <br>end; <br>/ <br><br>select id,link(id) from test group by id;<br><br>--方法三:<br><br>/*从Oracle 9i开始,开发者可以创建用户自定义的合计函数,除了PL/SQL外,还可以使用任何Oralce所支持的语言(如C++或者Java)来创建合计函数。TYPE头定义必须包含ODCIAggregateInitialize、ODCIAggregateIterate、ODCIAggregateMerge和ODCIAggregateTerminate这四个接口函数。*/<br><br>/*Initialize函数对数据组各个需要处理的字段各运行一次。自然的,我需要为每一个值准备一个新的清单,所以需要初始化持久变量list,这里初始化值为null。*/<br><br>/*Iterate函数处理返回的行,所以实际上是由它来创建返回的值的清单。先测试list是否为空,如果为空,就把list直接设置为所引入的value值;如果list变量非空,则给list添加一个逗号后再插入value值,list的最大允许字符数32767。*/ <br><br>/*Terminate函数在数据组的每个行的感兴趣字段数据被处理后执行。在这个函数中我只需简单的返回清单变量即可。*/ <br><br>/*Merge函数,用来返回成功标记的。*/<br><br>/*创建自己的合计函数扩展了Oracle统计和文本处理能力。*/<br><br><br>create or replace type t_cat as object <br>( <br>union_mc VARCHAR2(200), <br>static function ODCIAggregateInitialize(sctx IN OUT t_cat) return number, <br>member function ODCIAggregateIterate(self IN OUT t_cat,value IN varchar2) return number, <br>member function ODCIAggregateTerminate(self IN t_cat,returnValue OUT varchar2, flags IN number) return number, <br>member function ODCIAggregateMerge(self IN OUT t_cat,ctx2 IN t_cat) return number <br>); <br><br>create or replace type body t_cat is <br>static function ODCIAggregateInitialize(sctx IN OUT t_cat ) <br>return number is <br>begin <br>sctx := t_cat(''); <br>return ODCIConst.Success; <br>end; <br><br>member function ODCIAggregateIterate(self IN OUT t_cat, value IN varchar2) <br>return number is <br>begin <br>self.union_mc := self.union_mc || value; <br>return ODCIConst.Success; <br>end; <br><br>member function ODCIAggregateTerminate(self IN t_cat, returnValue OUT varchar2, flags IN number) return number is <br>begin <br>returnValue := self.union_mc; <br>return ODCIConst.Success; <br>end; <br><br>member function ODCIAggregateMerge(self IN OUT t_cat , ctx2 IN t_cat ) return number is <br>begin <br>return ODCIConst.Success; <br>end; <br>end; <br>/<br><br>/*如果你的Oracle服务器没有配置成支持并行处理的方式,可以去掉参数PARALLEL_ENABLE*/<br><br>create or replace function catstr(v_mc varchar2) return varchar2 PARALLEL_ENABLE AGGREGATE USING t_cat; <br>/<br><br>select id,catstr(mc) from test group by id;