存储过程中如何将两个拆分字符串关联合并为单表变量?
解决STRING_SPLIT拆分后对应行合并的问题
嘿,我完全懂你的困扰!用STRING_SPLIT直接关联确实会踩笛卡尔积的坑——这个函数默认不会返回元素的原始顺序索引,数据库根本不知道哪个11对应哪个1,只能全量匹配。下面给你几个靠谱的解决办法:
方法1:给拆分结果添加行号关联(兼容多数SQL Server版本)
通过ROW_NUMBER()给两个拆分后的结果集分别添加行号,再按行号关联,就能保证对应位置的元素匹配:
DECLARE @id NVARCHAR(100) = '1#2#3#4#5', @fid NVARCHAR(100) = '11#12#13#14#15'; SELECT f.fid, i.id FROM ( SELECT value AS fid, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn FROM STRING_SPLIT(@fid, '#') ) f INNER JOIN ( SELECT value AS id, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS rn FROM STRING_SPLIT(@id, '#') ) i ON f.rn = i.rn;
注意:
ORDER BY (SELECT NULL)在SQL Server中,对于STRING_SPLIT的结果多数场景下会保留原始顺序,但这并非官方承诺的行为。如果对顺序严谨性要求极高,建议用下面的方法。
方法2:用OPENJSON解析(顺序更可靠,兼容SQL Server 2016+)
把分隔符字符串转换成JSON数组,再用OPENJSON解析——这个函数会返回每个元素的索引(key列),我们可以直接用索引关联:
DECLARE @id NVARCHAR(100) = '1#2#3#4#5', @fid NVARCHAR(100) = '11#12#13#14#15'; SELECT f.value AS fid, i.value AS id FROM ( SELECT [value], [key] AS rn FROM OPENJSON('["' + REPLACE(@fid, '#', '","') + '"]') ) f INNER JOIN ( SELECT [value], [key] AS rn FROM OPENJSON('["' + REPLACE(@id, '#', '","') + '"]') ) i ON f.rn = i.rn;
这种方法的索引是明确基于原始字符串顺序生成的,不会有顺序错乱的风险,兼容性也不错。
方法3:用STRING_SPLIT的ordinal参数(SQL Server 2022/Azure SQL专属)
如果你的数据库是SQL Server 2022或者Azure SQL,STRING_SPLIT新增了第三个参数enable_ordinal,设置为1就会直接返回元素的序号列ordinal,代码会更简洁:
DECLARE @id NVARCHAR(100) = '1#2#3#4#5', @fid NVARCHAR(100) = '11#12#13#14#15'; SELECT f.value AS fid, i.value AS id FROM STRING_SPLIT(@fid, '#', 1) f INNER JOIN STRING_SPLIT(@id, '#', 1) i ON f.ordinal = i.ordinal;
这是最推荐的方法,官方保证顺序,代码也最干净。
内容的提问来源于stack exchange,提问作者Kshitij
相关产品推荐
相关产品推荐

