SQL无公共列按原行序拼接及逗号分隔字符串拆分问题求解
你遇到的问题根源是ROW_NUMBER() OVER (ORDER BY [Value])按字段值排序生成序号,自然会打乱字符串拆分后的原始顺序,只需要在拆分阶段直接获取元素的原始位置作为关联序号,即可实现按原位置一一匹配。
方案1:基于XML节点位置生成序号(兼容所有支持XML的SQL Server版本)
该方法利用XQuery内置的position()函数直接获取节点在原始XML中的顺序,和原字符串的元素顺序完全一致,无需额外排序。
完整代码如下:
DECLARE @ids nvarchar(max) = '1,2,3' DECLARE @guids nvarchar(max) = '0000000-0001-0000-0000-000000000000, `0000000-0022-0000-0000-000000000000`, `0000000-0013-0000-0000-000000000000' -- 清理guid字符串中的多余反引号、换行符 SET @guids = REPLACE(REPLACE(REPLACE(@guids, '`', ''), CHAR(10), ''), CHAR(13), '') -- 拆分id字符串,保留原始序号 DECLARE @xml_id xml SET @xml_id = N'<root><r>' + replace(@ids, ',' ,'</r><r>') + '</r></root>' -- 拆分guid字符串,保留原始序号 DECLARE @xml_guid xml SET @xml_guid = N'<root><r>' + replace(@guids, ',' ,'</r><r>') + '</r></root>' -- 按原始序号关联生成目标表 ;WITH cte_ids AS ( SELECT r.value('.','int') AS Id, r.value('position()', 'int') AS seqnum FROM @xml_id.nodes('//root/r') as records(r) ), cte_guids AS ( SELECT r.value('.','nvarchar(50)') AS Guid, r.value('position()', 'int') AS seqnum FROM @xml_guid.nodes('//root/r') as records(r) ) SELECT t1.Id, t2.Guid INTO Table1 FROM cte_ids t1 INNER JOIN cte_guids t2 ON t1.seqnum = t2.seqnum
方案2:使用内置STRING_SPLIT函数(仅适用于SQL Server 2022及以上、Azure SQL版本)
最新版本的STRING_SPLIT函数支持第三个参数enable_ordinal,开启后会直接返回元素的原始位置序号,代码更简洁:
DECLARE @ids nvarchar(max) = '1,2,3' DECLARE @guids nvarchar(max) = '0000000-0001-0000-0000-000000000000, `0000000-0022-0000-0000-000000000000`, `0000000-0013-0000-0000-000000000000' SET @guids = REPLACE(REPLACE(REPLACE(@guids, '`', ''), CHAR(10), ''), CHAR(13), '') SELECT t1.value AS Id, t2.value AS Guid INTO Table1 FROM STRING_SPLIT(@ids, ',', 1) t1 INNER JOIN STRING_SPLIT(@guids, ',', 1) t2 ON t1.ordinal = t2.ordinal
内容的提问来源于stack exchange,提问作者Tomas
相关产品推荐
相关产品推荐

