如何在Microsoft SQL Server Management Studio中按匹配user_id将多行合并为逗号分隔单行
问题原因
你当前代码的核心问题是拼接用的子查询没有关联外层的USER_ID过滤条件,导致子查询会把所有符合基础条件的POINT_ID全部拼接,每个USER_ID返回的都是全量拼接结果,没有按USER_ID做分组隔离。同时子查询没有同步外层的过滤条件,可能会混入不符合状态要求的记录。
修正后代码
SELECT c.USER_ID, STUFF( ( SELECT DISTINCT ',' + CAST(b.POINT_ID AS VARCHAR(10)) FROM DATABASE1 A LEFT JOIN DATABASE2 AS b ON a.SSCL_ID = b.SEC_ID -- 新增关联外层USER_ID,只取当前用户的POINT_ID WHERE A.USER_ID = c.USER_ID -- 同步外层过滤条件,保证数据一致性 AND A.RECORD_STATUS IN ('2','5') AND A.USER_STATUS = '1' FOR XML PATH(''), TYPE ).value('.', 'VARCHAR(MAX)'), -- 增加TYPE和value处理避免特殊字符转义问题 1, 1, '') AS POINT_ID_LIST FROM DATABASE1 c WHERE c.RECORD_STATUS IN ('2','5') AND c.USER_STATUS = '1' GROUP BY c.USER_ID
代码调整说明
- 新增
WHERE A.USER_ID = c.USER_ID:子查询和外层查询做USER_ID关联,保证每个用户只拼接自己对应的POINT_ID - 子查询同步外层的
RECORD_STATUS、USER_STATUS过滤条件:避免子查询返回不符合业务规则的无效记录 - 新增
TYPE和.value('.', 'VARCHAR(MAX)'):处理FOR XML PATH默认会把&、<这类特殊字符转义的问题,保证拼接结果和原始值一致
如果是SQL Server 2017及以上版本,还可以用更简单的STRING_AGG函数实现,代码更简洁:
SELECT A.USER_ID, STRING_AGG(DISTINCT CAST(b.POINT_ID AS VARCHAR(10)), ',') AS POINT_ID_LIST FROM DATABASE1 AS A LEFT JOIN DATABASE2 AS b ON a.SSCL_ID = b.SEC_ID WHERE A.RECORD_STATUS IN ('2','5') AND A.USER_STATUS = '1' GROUP BY A.USER_ID
内容的提问来源于stack exchange,提问作者Mystical Me
相关产品推荐
相关产品推荐

