如果一列的值与我想要的匹配: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;