The main function is STRING_AGG, which you can use the same way as other aggregate functions. Example:
select employee_id, string_agg( job_id ) job_list from job_history group by employee_id;Here's the output in SQL Plus:
EMPLOYEE_ID JOB_LIST
----------- ----------------------------------------
101 AC_ACCOUNT,AC_MGR
102 IT_PROG
114 ST_CLERK
122 ST_CLERK
176 SA_REP,SA_MAN
200 AD_ASST,AC_ACCOUNT
201 MK_REP
7 rows selected.
The delimiter by default is comma (,), and is controlled by a store package STRING_AGG_CONTROL. To change it, you can use:begin string_agg_control.g_delim := '|'; end; /Then run the sql again:
select employee_id, string_agg( job_id ) job_list from job_history group by employee_id;
EMPLOYEE_ID JOB_LIST
----------- ----------------------------------------
101 AC_ACCOUNT|AC_MGR
102 IT_PROG
114 ST_CLERK
122 ST_CLERK
176 SA_REP|SA_MAN
200 AD_ASST|AC_ACCOUNT
201 MK_REP
7 rows selected.
The function is implemented using an Oracle user defined type with the help of User-Defined Aggregates Interface. You can find more information in this doc.Sounds perfect? Not that much -- you cannot order the strings. That means the source strings appear in the aggregate string randomly.
The script is attached:
create or replace package string_agg_control IS
g_delim varchar2(100) := ',';
end;
/
CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
g_string VARCHAR2(32767),
g_delim VARCHAR2(100), -- Delimiter to seperate the strings
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER,
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER
);
/
SHOW ERRORS
CREATE OR REPLACE TYPE BODY t_string_agg IS
STATIC FUNCTION ODCIAggregateInitialize(sctx IN OUT t_string_agg)
RETURN NUMBER IS
BEGIN
sctx := t_string_agg( NULL, string_agg_control.g_delim );
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateIterate(self IN OUT t_string_agg,
value IN VARCHAR2 )
RETURN NUMBER IS
BEGIN
SELF.g_string := self.g_string || self.g_delim || value;
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateTerminate(self IN t_string_agg,
returnValue OUT VARCHAR2,
flags IN NUMBER)
RETURN NUMBER IS
BEGIN
returnValue := RTRIM(LTRIM(SELF.g_string, self.g_delim ), self.g_delim );
RETURN ODCIConst.Success;
END;
MEMBER FUNCTION ODCIAggregateMerge(self IN OUT t_string_agg,
ctx2 IN t_string_agg)
RETURN NUMBER IS
BEGIN
SELF.g_string := SELF.g_string || self.g_delim || ctx2.g_string;
RETURN ODCIConst.Success;
END;
END;
/
SHOW ERRORS
CREATE OR REPLACE FUNCTION string_agg (p_input VARCHAR2)
RETURN VARCHAR2
PARALLEL_ENABLE AGGREGATE USING t_string_agg;
/
SHOW ERRORS
2 comments:
BTW this is a cracking bit of work that has proved extremely useful. Many thanks. Simon
Thanκs for a marvelοus posting! Ι gеnuinely enϳoyed геаԁing it,
you're a great author.I will be sure to bookmark your blog and definitely will come back very soon. I want to encourage you continue your great job, have a nice holiday weekend!
my website - utah boat rental
Post a Comment