
Oracle RDBMS 11gR2 – LISTAGG – New aggregation operator for creating (comma) delimited strings
In our series on the 11g R2 release of the Oracle RDBMS, AMIS staff discusses various functions, features an facilities that have been added, improved or extended in this latest release. These articles are the fruit of several months of studying this new release and projecting which new features and changes would be the most useful to us in our daily practice. This article introduced the LISTAGG operator, new in 11gR2.
An example usage of LISTAGG:
select deptno
, avg(sal) avg_sal
, listagg( ename, ',')
within group (order by sal)
enames
from emp
group
by deptno
Oracle RDBMS 10g introduced the Collect operator. It could be used to aggregate values on all rows in a group into a collection – a predefined TABLE OF <some type>. This operator can be used in statements like this one:
create or replace type
ename_type as table of varchar2(30)
/
select deptno
, avg(sal) avg_sal
, cast
( collect(ename)
as ename_type
) enames
from emp
group
by deptno
/

There are some limitations on using this operator: it does not support an order by especially for the collected values, it requires a TYPE definition (usually TABLE OF VARCHAR2) that has to be created before the Collect can be used and it acts only as a pure Aggregate Function (typically in conjunction with a group by), it is not available as an Analytical function.
(edited) on second thoughts, I should have rephrased the above. First of all – as Laurent pointed out in his comment, an order by expression apparently is allowed with COLLECT (I never knew that one!) just as DISTINCT and UNIQUE can be used. I also found out that you can use COLLECT without predefining a collection type. If you execute a statement like collect(ename) as emps – without the cast to turn the collect outcome into a well defined collection, the database will generate a type for you, on the fly with a system generated name that is quite worthless, but it will work all the same.
The new LISTAGG is similar to yet different from the COLLECT: LISTAGG creates a delimiter (comma, period, colon, etc.) separated string of values. The LISTAGG takes an optional order by clause that specifies the sequence of the values in the string. It returns a VARCHAR2 – so no custom type needs to be set up. And: LISTAGG is available as Aggregate (with GROUP BY) and Analytical Function (with PARTITION clause).
A simple example of using LISTAGG:
select deptno
, avg(sal) avg_sal
, listagg( ename, ',') within group (order by sal)
enames
from emp
group
by deptno
/
The results returned by this query:

Here we used LISTAGG as an aggregate function, together with the GROUP BY that in this case indicates that the concattenated string with ENAME values should create this string per department. Within the string, the enames should be ordered by the salary values of the employees.
The next example is on using the LISTAGG as an analytical function, producing aggregate values in line with the records rather than grouped by into a summary result. So for each record processed, the delimiter separated string is produced, in the same way other analytical functions function. That means for example that we could have a ‘running delimited string’ if we would add an order by to the over() clause without a windowing clause.
Here we are after the list of employees (colleagues) that work in the same department as the employee being processed:
select deptno
, ename
, sal
, listagg( ename, ',')
within group (order by ename)
over (partition by deptno)
colleagues
from emp
order
by deptno
, ename
The results:

Resources
11gR2 SQL Language Reference on Collect
11gR2 SQL Language Reference on LISTAGG
the collect function in 10g – on Oracle-developer.net
Jouw toekomst als Oracle professional – AMIS !!EXTRA!! informatieavond over jouw ontwikkelingspad
24/1/2012 - 10:29 am
Tags: apex, Database, forms, Mobile, modernisering, Oracle, plsql, soa, sql
Posted in General | No comments
Als je dit leest en je bent Oracle professional – ontwikkelaar of administrator – is de kans groot dat je jouw carriere bent gestart in de jaren ‘90, in het tijdperk van Oracle7, Oracle Forms en Client/Server applicaties – net voor de opkomst van Java, internet, mobiel en SOA. Misschien ligt je start daar nog [...]
Factorial in Oracle SQL – using both new Recursive Subquery and classic Connect By approach
13/12/2011 - 10:33 am
Tags: connect by, factorial, recursive, recursive subquery factoring, sql
Posted in Database, Devel. + PL/SQL tools, Oracle | 5 comments
I regularly teach a masterclass on Oracle SQL. One of the topics I explore in depth is the use of the CONNECT BY query style to perform not just hierarchical queries but also networking or even generic recursive SQL. In Oracle Database 11g, the recursive subquery was formally introduced, the SQL Standard’s approach to this [...]
Weird ADF 11g requirement addressed with left outer join and modern SQL join syntax
13/12/2011 - 8:47 am
Tags: adf, bind parameter, bind variable, join, outer join, sql, viewobject
Posted in ADF & JHeadstart, Database, General, Oracle | No comments
The functional requirement was a little unusual. The page should either show all master-records or – depending on the value of a parameter – it should show exactly one master-record joined with exactly one detail-record. The use case was valid – that was exactly the functionality that was required.
In terms of EMP and DEPT -I [...]
ADF: The best way to indicate for records in a table the existence of details – or: the importance of up-to-date SQL knowledge
27/10/2011 - 9:15 pm
Tags: adf, scalar subquery, sql
Posted in ADF & JHeadstart, Java, JEE, OAS and WebLogic Server, Oracle | 3 comments
An interesting discussion arose in one of the projects I am involved in. The functional requirement at stake: show records in a table. In one of the columns, show an indicator (checkbox for example) that signals whether or not that particular record has a specific type of details associated with it. You could say that [...]
2 dagen seminar door Steven Feuerstein: Best of Oracle PL/SQL (8 en 9 december)
13/10/2011 - 7:00 am
Tags: 11g, Database, feuerstein, plsql, programming, sql, steven, steven feuerstein, toad
Posted in Announce, Books, Cloud, DBA, Database, Databases, Devel. + PL/SQL tools, General, IT Architecture, Oracle, Oracle Development Tools, Oracle E-Business Suite, SOA & Oracle Fusion Middleware, Software Development, Test, Tools, Unstructured Data | No comments
In dit tweedaagse seminar neemt Steven Feuerstein je mee ver voorbij de basismogelijkheden van PL/SQL. Steven zal tijdens dit seminar de best practices behandelen die hij op tientallen plekken in de wereld heeft verzameld en die hij ook mede door zijn nauwe samenwerking met het PL/SQL product team van Oracle kan verifiëren en aanscherpen. Hij [...]
OOW 2011 – What’s New, Improved and Coming in Oracle Application Development
3/10/2011 - 7:12 pm
Tags: apex, Database, Java, networking, ODP.net, PHP, sql, sql developer, tom kyte
Posted in Database, Devel. + PL/SQL tools, General, Software Development | No comments
Currently at Tom Kyte’s session regarding topics new, improved or coming in Oracle Application Development. Tom told about the history APEX has gone thru and the current setup with the APEX Listener and even the “PL/SQL Gateway” was mentioned. I always have to laugh a bit because this last one touches the XDB Protocol Server [...]
Data Integriteit anno 2011 – Hands-on met Toon Koppelaars en RuleGen 3.0 bij AMIS op dinsdag 27 september
22/9/2011 - 8:22 am
Tags: architecture, business rules, constraint, Database, ruleframe, rulege, sql
Posted in AMIS, Database, Devel. + PL/SQL tools, General, Oracle | No comments
datum: dinsdag 27 september; 16.30 uur
locatie: AMIS, Edisonbaan 15, Nieuwegein
sprekers: Toon Koppelaars en Lucas Jellema
Het belang van data integriteit behoeft geen toelichting – als het goed is. Vrijwel iedere enterprise applicatie is gebouwd op het fundament van een database. Robuustheid van die database en absolute betrouwbaarheid van de gegevens daarin zijn. essentieel. [...]
Update day to second interval column in selection from time gaps table by parsing strings containing time differences using REGEXP_SUBSTR
25/7/2011 - 4:08 pm
Tags: inline view, interval, regexp_substr, regular expressions, sql
Posted in Database, Devel. + PL/SQL tools, Oracle | 2 comments
An apparently trivial challenge that still took me bit longer than expected. What is the situation: I have a table with two columns (of interest). One is a column called gap, with values like these:
Each value represents a time difference. These values are strings – not much use to calculate with. Therefore a second column [...]
RuleGen 3.0 – the latest, leanest and most robust solution for complex data constraints in an Oracle Database
6/7/2011 - 11:58 am
Tags: business rule, constraint, Database, rulefram, rulegen, sql, transaction
Posted in Database, Databases, Devel. + PL/SQL tools, J(2)EE/Java, Oracle | No comments
No matter how complex the enterprise and application architectures become, no matter the number of tiers, services, devices and user interfaces – at the heart of most enterprises will be a relational database.
And no matter how hard we try to implement a fully service based architecture or a multi-purpose business tier (for example using EJBs) [...]
Using SQL UNPIVOT to prepare data for dynamic ADF Faces User Interfaces
3/7/2011 - 6:40 am
Tags: adf, bar chart, sql, unpivot
Posted in ADF & JHeadstart, Database, Devel. + PL/SQL tools, J(2)EE/Java, Oracle | No comments
The UNPIVOT operator was introduced in Oracle Database 11g – see for example: http://technology.amis.nl/blog/2421/the-oracle-11g-unpivot-operator-turning-columns-into-rows. In Oracle, the UNPIVOT operation is the process of turning Columns to Rows. Put simply, by applying the UNPIVOT operator to a number of columns, every row is split into that same number of rows. Each of these rows has two [...]


2/9/2009 - 10:11 am
There are some limitations on using this [COLLECT] operator: it does not support an order by especially for the collected values
Really?
select collect(ename order by ename) from emp
seems to be a valid syntax
2/9/2009 - 1:30 pm
Oops, in that case I have overlooked that particular feature in the COLLECT operator. And I stand corrected. That is the risk you run with such a sophisticated audience! Will we meet at OOW Laurent? Thanks for your comment! Best regards, Lucas
2/9/2009 - 5:23 pm
No, I have no plan to go to OOW this year… did you submit some trivia questions to Lilian?
Kind regards
5/9/2009 - 11:54 pm
The possibility to use the collect function in combination unique or distinct or order by is new Oracle 11gr1 . I believe it isn’t possible in Oracle 10.
I hoped that listagg would return a clob instead of a varchar2. What happens when the 4000 limit is surpassed? I can’t test it because I don’t have Linux so I can’t install 11gr2 yet.
4/12/2009 - 8:11 pm
Hi Lucas,
That was good examples and feature. But how can you implement below same thing in 10g using collect or any other method
select deptno
, avg(sal) avg_sal
, listagg( ename, ‘,’) within group (order by sal)
enames
from emp
group
by deptno
/