仅在值存在差异的情况下汇总列中的值,我不想汇总所有值

时间:2019-11-05 09:58:04

标签: sql sql-server

我想在哪一列的值匹配的地方: 1.仅在其他两个值之间存在差异的情况下汇总其他列中的数据 2.如果值相同,则取值

示例数据

Name  MiddleName Surname Age 
Ryan   David     Smith   28
Ryan   David     Smith   29
Sean   John       Johnson 37
Sean   John       Johnson 38

所需结果:

Name  MiddleName Surname Age
Ryan    David    Smith   28, 29
Sean    John     Johnson 37, 38

名称ryan出现两次,因此只希望汇总其他字段的数据,其中两行的数据不同。

姓氏在两行中都是Smith,因此无需汇总,只想在一行中填充为Smith。

年龄不同,因此希望将两行的年龄汇总为一行

塞恩·约翰逊(Sean Johnson)记录我想汇总年龄,因为它们不同,但不是中间名,因为两个记录都相同

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

结果不理想:

Name    MiddleName Surname Age
Ryan    David      Smith   28, 29
Sean    John, John Johnson 37, 38

2 个答案:

答案 0 :(得分:1)

按您希望相同的所有值分组:

SELECT name, middlename, surname, string_agg(age, ',')
FROM t
GROUP BY name, middlename, surname;

答案 1 :(得分:1)

最初,您可以使用所有不同的名称,然后将它们添加到子查询中的汇总中间名,姓氏和年龄,这些子查询之前是我们先前计算为CTE的每个名字的独特中间名,姓氏和年龄。

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

如果SQL Server支持 string_agg(DISTINCT middlename,','),则要简单得多,但是AFAIK我们不知道何时可用,因此我们需要首先计算不同的值分别。

我不知道是否有一种更简单的方法来获得相同的结果,但是这种方法应该可以为您提供所需的结果。