LISTAGG() Function in Oracle

In Oracle, the LISTAGG() function enables us to combine data from multiple rows in to a single row.

We have the option of specifying a separator (such as a comma). We can also order the results produced by the LISTAGG() function, and more.

Syntax

The syntax goes like this:

LISTAGG( [ ALL | DISTINCT ] measure_expr [, 'delimiter'] [listagg_overflow_clause] )
  [ WITHIN GROUP order_by_clause ] [OVER query_partition_clause]

Where listagg_overflow_clause is:

{ ON OVERFLOW ERROR }
|
{ ON OVERFLOW TRUNCATE [ 'truncation-indicator' ] [ { WITH | WITHOUT } COUNT ] }

Example

Suppose we run the following query:

SELECT region_name
FROM regions;

Result:

              REGION_NAME 
_________________________ 
Europe                    
Americas                  
Asia                      
Middle East and Africa    

We can use LISTAGG() to convert those results into a comma separated list:

SELECT LISTAGG(region_name, ', ')
FROM regions;

Result:

                         LISTAGG(REGION_NAME,',') 
_________________________________________________ 
Europe, Americas, Asia, Middle East and Africa    

Change the Separator

We can change the second argument to a different separator:

SELECT LISTAGG(region_name, '; ') 
FROM regions;

Result:

Europe; Americas; Asia; Middle East and Africa 

Omit the Separator

We can omit the second argument to have each value concatenated without a separator:

SELECT LISTAGG(region_name) 
FROM regions;

Result:

EuropeAmericasAsiaMiddle East and Africa

Order the Results

We can use the WITHIN GROUP (ORDER BY...) clause to order the output of the LISTAGG() function:

SELECT LISTAGG(region_name, ',') WITHIN GROUP (ORDER BY region_name ASC) 
FROM regions;

Result:

Americas,Asia,Europe,Middle East and Africa

Usage in Grouped Queries

We can use the LISTAGG() function within a grouped query to provide results like this:

SELECT 
    region_id,
    LISTAGG(country_id, ', ') WITHIN GROUP (ORDER BY country_id ASC) AS "Countries"
FROM countries
GROUP BY region_id
ORDER BY region_id;

Result:

   REGION_ID                         Countries 
____________ _________________________________ 
           1 BE, CH, DE, DK, FR, IT, NL, UK    
           2 AR, BR, CA, MX, US                
           3 AU, CN, HK, IN, JP, SG            
           4 EG, IL, KW, NG, ZM, ZW           

Return Only Distinct Values

We can use the DISTINCT clause to return only unique values:

SELECT LISTAGG(DISTINCT region_id, ', ') 
FROM regions;

Result:

1, 2, 3, 4

See Oracle’s documentation for more details on what you can do with this function.