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

  • 本文关键字:我不想 情况下 存在 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

Name ryan出现两次,因此希望仅在两行数据不同的情况下聚合其他字段"姓"one_answers"年龄"的数据。

姓氏在两行中都是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

您可以首先获取所有不同的名称,并将它们添加到子查询中的聚合中间名、姓氏和年龄,这些子查询覆盖了我们之前计算为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我们不知道它什么时候可用,那么它会简单得多,所以我们需要首先分别计算不同的值。

我不知道是否有更简单的方法可以得到同样的结果,但这个方法应该能得到你要求的结果。

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

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

相关内容

最新更新