MS SQL:重复字段场景下合并查询结果至同一列(附优化代码)
在MS SQL中合并同一RecNo下的多条评论至单列
我明白你现在需要把同一RecNo对应的多条评论合并到单个列里,同时让RecNo和Date只显示唯一值对吧?在MS SQL里有几种常用的方法来实现这个需求,我给你整理一下最实用的两种:
方法1:使用STRING_AGG(SQL Server 2017及以上版本)
这个方法是最简洁的,SQL Server 2017及以后版本支持原生的字符串聚合函数,直接就能把多行结果合并成一行:
SELECT AMS.arecno AS [RecNo], CONVERT(DATE, AMS.adate) AS [Date], -- 合并同一RecNo下的所有评论,用分号分隔(可自定义分隔符) STRING_AGG(ac.acomment, '; ') AS [Comments] FROM amain AS AMS LEFT JOIN asfat AS ASF ON AMS.arecno = ASF.afatrecno LEFT JOIN acomments AS ac ON ac.areportno = ASF.afatrecno GROUP BY AMS.arecno, CONVERT(DATE, AMS.adate) ORDER BY AMS.arecno DESC
关键点说明:
- 用
GROUP BY对主表的唯一标识字段(RecNo和转换后的Date)分组,确保这两个字段只显示唯一值 STRING_AGG(ac.acomment, '; ')会把同一分组下的所有acomment值用指定的分隔符拼接起来,空值会自动忽略
方法2:使用FOR XML PATH(兼容SQL Server 2016及更早版本)
如果你的SQL Server版本比较旧,不支持STRING_AGG,可以用传统的FOR XML PATH方法来实现:
SELECT DISTINCT AMS.arecno AS [RecNo], CONVERT(DATE, AMS.adate) AS [Date], -- 用STUFF去掉开头的分隔符,再通过FOR XML PATH拼接评论 STUFF(( SELECT '; ' + ac2.acomment FROM asfat AS ASF2 LEFT JOIN acomments AS ac2 ON ac2.areportno = ASF2.afatrecno WHERE ASF2.afatrecno = AMS.arecno FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS [Comments] FROM amain AS AMS LEFT JOIN asfat AS ASF ON AMS.arecno = ASF.afatrecno LEFT JOIN acomments AS ac ON ac.areportno = ASF.afatrecno ORDER BY AMS.arecno DESC
关键点说明:
- 子查询通过
FOR XML PATH('')把多条评论拼接成带分隔符的字符串 STUFF函数用来去掉字符串开头多余的分隔符(这里是开头的;)DISTINCT确保RecNo和Date只显示唯一值
示例结果
按照你的数据示例,最终查询结果会是这样的:
| RecNo | Date | Comments |
|---|---|---|
| 6548 | 2018-01-01 | 评论1; 评论2 |
| 1234 | 2017-01-01 | 测试评论; 另一条评论 |
内容的提问来源于stack exchange,提问作者fred
相关产品推荐
相关产品推荐

