Search code examples
sqlaggregationsql-server-2017

Aggregate values in columns ONLY there is a difference


Where the values of one column match I want to:

  1. aggregate the data in the other columns where there is a different between the two values
  2. If the values are the same the take the value

Example data

Name  Surname Age
Ryan  Smith   28
Ryan  Smith   29
Sean  Johnson 37

Desired result:

Name  Surname Age
Ryan  Smith   28, 29
Sean  Johnson 37

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 is unique for all columns so no need to aggregate or amend anything

I have tried string_agg function but this gives the result:

Name  Surname          Age
Ryan  Smith, Smith     28,29
Sean  Johnson           37

It aggregates all fields irrespective of whether the data between the two rows is different or not.


Solution

  • You can use:

    select name, string_agg(distinct surname, ',') as surname, string_agg(age, ',')
    from t
    group by name;
    

    This assumes that all names are unique -- that seems like a strong assumption for most datasets.