Listagg Alternative in Oracle 10G

LISTAGG alternative in Oracle 10g

Try using XMLAGG like this:

select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;

If you need the concatenation in a particular order, say increasing order of SiteId, then add an order by clause in the xmlagg:

select
p.PeopleID,
rtrim(xmlagg(xmlelement(e, s.SiteName, ',')
order by s.SiteId).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
group by p.PeopleID;

EDIT:

If you want display result for all those people which are assigned to site 100:

select p.PeopleID,
rtrim(xmlagg(
xmlelement(e, s.SiteName, ',') order by s.SiteId
).extract('//text()').getclobval(), ',')
from people p
join site s on p.SiteID = s.SiteID
join (
select distinct PeopleID
from people
where siteID = 1
) p2 on p.PeopleID = p2.PeopleID
group by p.PeopleID;

alternative to listagg in Oracle?

Use collect or write your own aggregation function.

listagg alternative in Oracle

I use the following user-defined function as suggested by Tom Kyte of asktom - performance is acceptable to me (although it will not work in Oracle 8). Can you try this ?

CREATE OR REPLACE TYPE t_string_agg AS OBJECT
(
g_string VARCHAR2(32767),

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);
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 || ',' || 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, ','), ',');
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 || ',' || 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

Application,

COLUMN employees FORMAT A50

SELECT deptno, string_agg(ename) AS employees
FROM emp
GROUP BY deptno;

DEPTNO EMPLOYEES
---------- --------------------------------------------------
10 CLARK,KING,MILLER
20 SMITH,FORD,ADAMS,SCOTT,JONES
30 ALLEN,BLAKE,MARTIN,TURNER,JAMES,WARD

3 rows selected.

Oracle SQL: Alternative to aggregate large texts (when exceeding Listagg limit)

One of possible method.

select xmlagg(xmlelement(xxx,'ITEM NO.: ' || m.ITEM || 
' -nl-ARTICLE: ' || a.ARTICLE ||
' -nl-NET: ' || m.NET ||
' -nl-TAX: ' || NVL(m.TAX, 0) ||
' -nl-GROSS: ' || (m.NET + m.TAX),
' -nl--nl-'||',<-separator').extract('//text()') order m.S_ID).getClobval() from mytable
group by ...

2nd method.
oracle allows to creat own aggregation function user defined aggregation function



Related Topics



Leave a reply



Submit