MSSQL如何实现分组去重并拼接关联表对应字段为字符串?
问题原因分析
你原有代码存在以下问题:
- 采用自连接笛卡尔积的两两拼接逻辑,仅能适配每个姓名对应2个Zone的场景。当Zone数量≥3时(比如Alex有3个Zone),会生成多组两两拼接的错误结果,无法得到完整的全量Zone拼接字符串
- 没有实现按姓名分组的聚合逻辑,也没有处理Zone去重的需求
修复方案
方案1:MSSQL 2017及以上版本(推荐)
直接使用内置字符串聚合函数STRING_AGG实现,代码简洁性能更高:
SELECT a.Name, STRING_AGG(DISTINCT d.Zone, ',') WITHIN GROUP (ORDER BY d.Zone) AS Zone FROM Animals a INNER JOIN Details d ON a.ID = d.ID GROUP BY a.Name
其中DISTINCT保证Zone值去重,WITHIN GROUP (ORDER BY)用来控制拼接顺序,和你期望的输出顺序保持一致。
方案2:MSSQL 2016及更早版本
用FOR XML PATH语法实现兼容版本:
SELECT a.Name, STUFF( (SELECT DISTINCT ',' + d.Zone FROM Details d WHERE d.ID = a.ID ORDER BY ',' + d.Zone FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 1, '') AS Zone FROM Animals a GROUP BY a.ID, a.Name
其中STUFF函数用来去掉拼接生成的开头多余逗号,TYPE+value写法可以避免特殊字符被自动转义的问题。
内容的提问来源于stack exchange,提问作者Anjali
相关产品推荐
相关产品推荐

