'Postgresql pivot row data without aggregate function

I have this table:

create table student
(
    key serial primary key,
    id int, 
    type_name text,
    updated_by text,
    updated date, 
    text_data text,
    int_data int
); 

Sample table and data is here

A student id may have multiple rows(marks) for same subject. I would need to pivot all marks of each students for each subject.

I'm trying to pivot data with below query

select 
    id,
    max(updated_by) as updated_by,
    max(updated) as updated,
    max(case when type_name='Name' then text_data end) as "Name",
    max(case when type_name='Math' then int_data end) as "Math",
    max(case when type_name='English' then int_data end) as "English",
    max(case when type_name='Social' then int_data end) as "Social",
    max(case when type_name='Science' then int_data end) as "Science"
from
    stud 
group by 
    id

But this is not giving all marks for id 1 and in Math subject has marks 8 and 5. since i used max function in my query, i'm getting single value.

But it seems without aggregate function we can't do group_by.

Is there way in Postgresql to pivot data without aggregate functions to get below expected output

enter image description here

Thanks



Solution 1:[1]

What you need as another aggregation, namely STRING_AGG() along with FILTER clause such as

SELECT id,
       MAX(text_data) AS "Name",
       STRING_AGG ( int_data::TEXT, ',' ORDER BY key ) FILTER (WHERE type_name='Math') AS "Math",
       STRING_AGG ( int_data::TEXT, ',' ORDER BY key ) FILTER (WHERE type_name='English') AS "English",
       STRING_AGG ( int_data::TEXT, ',' ORDER BY key ) FILTER (WHERE type_name='Social') AS "Social",
       STRING_AGG ( int_data::TEXT, ',' ORDER BY key ) FILTER (WHERE type_name='Science') AS "Science"
  FROM stud 
 GROUP BY id

Demo

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Barbaros Özhan