Reputation: 69
Where the values of one column match I want to: 1.aggregate the data in the other columns ONLY where there is a different between the two values 2.If the values are the same the take the value
Example data
Name MiddleName Surname Age
Ryan David Smith 28
Ryan David Smith 29
Sean John Johnson 37
Sean John Johnson 38
Desired result:
Name MiddleName Surname Age
Ryan David Smith 28, 29
Sean John Johnson 37, 38
Name ryan appears twice, so want to aggregate the data for the other fields surname and age ONLY where the data is different for the two rows.
Surname is Smith in both rows so no need to aggregate, just want to populate as Smith in one row.
Age is different so want to aggregate the ages for the two rows into one row
Sean Johnson record i want to aggregate the ages as they are different, but not the middle name as this is the same for both records
select name, string_agg(distinct middlename, ','), string_agg(distinct surname, ',') as surname, string_agg(age, ',')
from t
group by name;
result which is not what is desired:
Name MiddleName Surname Age
Ryan David Smith 28, 29
Sean John, John Johnson 37, 38
Upvotes: 0
Views: 57
Reputation: 6465
You can initially take all the different names and add them the aggregated middlenames, surnames and ages on subqueries over the distincts middlnames, surnames and ages for each name that we have previously calculated as CTEs.
with middlenames as (
select distinct name, middlename
from t
),
surnames as (
select distinct name, surname
from t
)
ages as (
select distinct name, age
from t
)
select distinct name,
(select string_agg(middlename, ',') from middlenames m where m.name = t.name) as middlenames,
(select string_agg(surname, ',') from surnames s where s.name = t.name) as surnames,
(select string_agg(age, ',') from ages a where a.name = t.name) as ages
from t
It would be much simpler if SQL Server supported string_agg(DISTINCT middlename, ',') but AFAIK we don't know when it will be available, so we need to first calculate the distinct values separately.
I don't know if there is a simpler way to get these same results, but this one should get you the result you asked for.
Upvotes: 1
Reputation: 52654
Group by all the values you want to be the same:
SELECT name, middlename, surname, string_agg(age, ',')
FROM t
GROUP BY name, middlename, surname;
Upvotes: 1