I want to aggregate rows using the string aggregate function, however one column is an array.
I have three columns: Employee, Year, Grades. The column Grade is an array. Example:
Row (1) : Employee: Tom | Year: 2019 | Grades: 11,33
Row (2) : Employee: Tom | Year: 2018 | Grades: 45,24,54
'Grade' column is an array. It represents grades for the different tests he took that year
select
Employee,
string_agg (distinct Year, ','),
string_agg (distinct Grades, ',')
from Employee_grades
group by 1
ERROR:
function string_agg(bigint[], unknown) does not exist Hint: No function matches the given name and argument types. You might need to add explicit type casts.
You should use casting:
select Employee,
string_agg(distinct Year::text, ','),
string_agg(distinct Grades::text, ',')
from Employee_grades
group by Employee -- GROUP BY 1 is a bad practice
If you don't really care about removing duplicates, you can convert to a string using array_to_string():
select employee, array_agg(distinct year),
string_agg(array_to_string(grades, ','), ',')
from (values ('Tom', 2019, array[11, 33]),
('Tom', 2018, array[10, 20, 30])
) v(employee, year, grades)
group by employee;
If you actually want to remove duplicates, this is a bit trickier. Unnesting and de-duping may be the only approach:
with t as (
select *
from (values ('Tom', 2019, array[11, 33]),
('Tom', 2018, array[11, 20, 30])
) v(employee, year, grades)
)
select t.*,
(select array_agg(distinct grade)
from t t2 cross join lateral
unnest(grades) grade
where t2.employee = t.employee
) as grades
from (select employee, array_agg(distinct year) as year
from t
group by t.employee
) t;
I prefer to leave the results as arrays, but the results can easily be converted to strings if you prefer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With