Does Oracle have its own implementation of SQL Server stuff
function?
Stuff allows you to receive one value from a multi row select. Consider my situati
Execute below three functions.
Function 1
create or replace type stragg_type as object ( string varchar2(4000),
static function ODCIAggregateInitialize ( sctx in out stragg_type ) return number ,
member function ODCIAggregateIterate ( self in out stragg_type , value in varchar2 ) return number ,
member function ODCIAggregateTerminate ( self in stragg_type, returnvalue out varchar2, flags in number ) return number ,
member function ODCIAggregateMerge ( self in out stragg_type, ctx2 in stragg_type ) return number );
/
function 2
create or replace type body stragg_type is
static function ODCIAggregateInitialize ( sctx in out stragg_type ) return number is begin
sctx := stragg_type( null ) ; return ODCIConst.Success ;
end;
member function ODCIAggregateIterate ( self in out stragg_type , value in varchar2 ) return number is begin
self.string := self.string || ',' || value ; return ODCIConst.Success;
end;
member function ODCIAggregateTerminate ( self
in stragg_type , returnvalue out varchar2 , flags in number ) return number is beginreturnValue := ltrim( self.string, ',' ); return ODCIConst.Success;
end;
member function ODCIAggregateMerge
( self in out stragg_type , ctx2 in stragg_type ) return number is beginself.string := self.string || ctx2.string; return ODCIConst.Success;
end;
end; /
function 3
create or replace function stragg ( input varchar2 ) return varchar2
deterministic parallel_enable
aggregate using stragg_type ; /
Example Table :emp name | salary a
| 100 a | 200 a | 300 b | 400 b | 500 c | 600 c | 700 d
| 800select name , STRAGG( salary) as string from emp group by name;
output:
a | 100,200,300
b | 400,500
c | 600,700
d | 800
The "no add-ons/no undocumented functions" Oracle solution (prior to 11.2 as Tony mentions) is:
select c1, ltrim(sys_connect_by_path(c2,','),',') persons
from
(
select c1, c2,
row_number() over (partition by c1 order by c2 ) rn
from
(
select house_ref c1, person c2
from housetable
)
)
where connect_by_isleaf=1
connect by prior rn+1 =rn and prior c1 = c1
start with rn=1
;
You can write a custom aggregate function to do this. This string you generate is limited to 4k characters.
http://www.sqlsnippets.com/en/topic-11591.html
There is an undocumented, unsupported function WMSYS.WM_CONCAT
to do the same thing.
http://www.psoug.org/reference/undocumented.html
Oracle 11.2 includes a new function LISTAGG to do this.
Prior to that you could use Tom Kyte's STRAGG function.