SQL Server中STUFF()分组拼接失效问题及解决方法
旧版SQL Server按分组拼接行转列问题解决
问题背景
使用旧版本SQL Server,尝试将行按CleanName分组,拼接对应FullName列并求和Total。使用STUFF()函数时出现错误:所有行的FullName被拼接在一起,而非按分组单独拼接。
基础临时表#Temp结构
| CleanName | FullName | Total |
|---|---|---|
| Doe, Jane | DO, JANE | 4 |
| Doe, Jane | DOE, JANE S. | 15 |
| Doe, Jane | Doe, J. | 23 |
| Smith, John | Smith, J. | 4 |
| Smith, John | Smith, Jon | 10 |
| Smith, John | Smith, John | 103 |
期望结果
| CleanName | Concat_FullName | Sum(Total) |
|---|---|---|
| Doe, Jane | DO, JANE; DOE, JANE S.; Doe, J. | 42 |
| Smith, John | Smith, J.; Smith, Jon; Smith, John | 117 |
错误代码
SELECT STAND_PRESC_NAME, CONCAT_FULLNAME = STUFF(( SELECT '; ' + FULLNAME FROM #TEMP FOR XML PATH(''), TYPE).value('.', 'VARCHAR(MAX)'),1,1,''), SUM(TOTAL) FROM #TEMP GROUP BY STAND_PRESC_NAME
错误结果
| CleanName | Concat_FullName | Sum(Total) |
|---|---|---|
| Doe, Jane | DO, JANE; DOE, JANE S.; Doe, J.; Smith, J.; Smith, Jon; Smith, John | 42 |
| Smith, John | DO, JANE; DOE, JANE S.; Doe, J.; Smith, J.; Smith, Jon; Smith, John | 117 |
解决方法
问题核心是子查询未关联外部查询的分组字段,导致每次返回所有FullName。需在子查询中添加WHERE条件关联分组字段,同时修正STUFF的参数:
修正后的代码
SELECT CleanName, Concat_FullName = STUFF(( SELECT '; ' + FullName FROM #Temp t2 WHERE t2.CleanName = t1.CleanName -- 关联分组字段,仅拼接当前组的FullName FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(MAX)'), 1, 2, ''), -- 移除开头的'; '(两个字符) SUM(Total) AS [Sum(Total)] FROM #Temp t1 GROUP BY CleanName
关键说明
- 分组关联:通过
t2.CleanName = t1.CleanName限定子查询仅查询当前分组的记录,实现按组拼接。 - STUFF参数修正:因为拼接前缀是
'; '(两个字符),所以STUFF第三个参数设为2,去掉开头多余的分隔符。 - 字段名统一:将原代码中错误的
STAND_PRESC_NAME改为临时表实际字段CleanName,避免字段不匹配。
内容的提问来源于stack exchange,提问作者JayA
相关产品推荐
相关产品推荐

