SQL Server中如何将列值拼接为逗号分隔的字符串
T-SQL 实现分组后逗号分隔字符串拼接方案
针对按MbrID分组、将Grade与拆分后的Rating值拼接为指定格式FinalRating的需求,可按「先拆分多值字段、再拼接Grade、最后分组聚合」的逻辑实现,不同SQL Server版本对应实现方式如下:
核心逻辑
- 原始表中Rating字段本身存储了逗号分隔的多值,首先需要将每个Rating拆分为单个值,与对应Grade拼接为
Grade+Rating值的独立子项,例如Grade为A、Rating为12,13的记录会拆分为A12、A13两个子项 - 按MbrID分组,将同组下所有子项用逗号拼接,得到最终的FinalRating字段
SQL Server 2017及以上版本(推荐方案)
使用原生STRING_SPLIT拆分字符串、STRING_AGG做分组聚合,写法简洁性能更好:
WITH SplitSubItem AS ( SELECT r.MbrID, -- 拼接Grade和拆分后的单个Rating值 CONCAT(r.Grade, s.value) AS RatingItem FROM Rating r -- 按逗号拆分Rating字段的多值 CROSS APPLY STRING_SPLIT(r.Rating, ',') s ) SELECT MbrID, -- 分组拼接所有子项,WITHIN GROUP指定拼接顺序匹配示例要求 STRING_AGG(RatingItem, ',') WITHIN GROUP (ORDER BY LEFT(RatingItem,1), CAST(STUFF(RatingItem,1,1,'') AS INT)) AS FinalRating FROM SplitSubItem GROUP BY MbrID;
上述排序逻辑可以保证输出顺序严格按照A→B→C的Grade顺序、同Grade下按Rating数值升序排列,和示例要求的
A12,A13,B10,B15,C7,C3结果完全匹配。
SQL Server 2016及以下兼容版本
低版本没有STRING_AGG函数,可通过FOR XML PATH实现字符串聚合,拆分逻辑替换为XML方式兼容:
SELECT DISTINCT r1.MbrID, STUFF( (SELECT ',' + CONCAT(r2.Grade, Split.item.value('.', 'VARCHAR(20)')) FROM Rating r2 CROSS APPLY ( -- XML方式拆分逗号分隔的Rating值 SELECT CAST('<v>'+REPLACE(r2.Rating, ',', '</v><v>')+'</v>' AS XML) AS RatingXml ) x CROSS APPLY x.RatingXml.nodes('/v') AS Split(item) WHERE r2.MbrID = r1.MbrID -- 调整ORDER BY逻辑匹配输出顺序 ORDER BY r2.Grade, CAST(Split.item.value('.', 'VARCHAR(20)') AS INT) FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(MAX)'), 1, 1, '' ) AS FinalRating FROM Rating r1;
注意事项
- 如果Rating字段为数值类型,拼接前需要显式转换为字符串类型,避免隐式类型转换导致的报错
- 若使用SQL Server 2022及以上版本,
STRING_SPLIT支持传入enable_ordinal参数返回拆分值的原始位置,可直接按该位置排序保证和原始存储顺序一致 - 不要依赖无ordinal参数的
STRING_SPLIT返回顺序,该顺序不保证和原字符串中值的顺序完全一致
内容的提问来源于stack exchange,提问作者Robin
相关产品推荐
相关产品推荐

