Use the aggregate function string_agg()
.
SELECT user_name, string_agg("role", ', ') AS roles
FROM tbl
GROUP BY 1
ORDER BY 1;
If you want the list in alphabetical order:
string_agg("role", ', ' ORDER BY "role")
Question
I need to do an ETL job and I have a table that looks like this
user_name | role
----------+------
User A | Admin
User A | System
User B | Editor
User B | Power User
User B | System
I want to transform that into
user_name | role
----------+------
User A | Admin, System
User B | Editor, Power User, System
I thought about creating temp tables and using row_number() over (partition by user_name)
but it started to get messy. Is there a better way to get that output?
Solution
Use the aggregate function string_agg()
.
SELECT user_name, string_agg("role", ', ') AS roles
FROM tbl
GROUP BY 1
ORDER BY 1;
If you want the list in alphabetical order:
string_agg("role", ', ' ORDER BY "role")
OTHER TIPS
SELECT user_name,
array_to_string(array(
select role
from my_table
where user_name =m.user_name
order by user_name
), ', '
) combined_rows
from my_table m
group by 1
Link to SQL Fiddle