2

In Microsoft SQL Server (T-SQL), there is a succinct, elegant, and performant set-oriented way to populate a VARCHAR variable with a concatenation of values from multiple rows in a table, i.e.:

DECLARE @vals NVARCHAR(MAX)
SELECT @vals = ISNULL(@vals + ',', '')
+ <some_varchar_column>
FROM <some_table>

Populates @vals with a comma-delimited string of all values in some_column from all rows of some_table (e.g., "value1,value2,value3, ...").

How do I do something similar in Oracle PL/SQL in a similarly elegant way (without needing to write a loop/cursor)?

0xdb
  • 3,539
  • 1
  • 21
  • 37
Cade Bryant
  • 737
  • 2
  • 7
  • 19

2 Answers2

8

This?

SQL> select listagg(dname, ',') within group (order by dname) result
  2  from dept;

RESULT
-------------------------------------------------------------------------
ACCOUNTING,OPERATIONS,RESEARCH,SALES

SQL>
Littlefoot
  • 131,892
  • 15
  • 35
  • 57
2

Sometimes it makes sense to implement an own function. it's really easy (db<>fiddle):

select * from vals
/
        ID VAL                                          
---------- ---------------------------------------------
         1 value1                                       
         1 value2                                       
         2 value3                                       
         2 value4                                       
         2 value5                                       
         3 value6                                       

create or replace type listofvals is table of varchar2 (64)
/
with function mylistagg (vals listofvals, delimiter char := ',') return varchar2 is
    ret varchar2 (32767);
begin 
    for i in 1..vals.count loop 
        ret := ret||vals(i)||delimiter; end loop;
    return rtrim (ret, delimiter);
end; 
select id, mylistagg (cast (collect (val order by val) as listofvals), ' -> ') res
from vals
group by id
/

Result:

        ID RES                             
---------- --------------------------------
         1 value1->value2                  
         2 value3->value4->value5          
         3 value6                          
0xdb
  • 3,539
  • 1
  • 21
  • 37