无需游标,在SELECT语句中拆分T-SQL列值的方法
无游标实现字符串拆分展平
方法一:使用STRING_SPLIT(SQL Server 2016+ 推荐)
直接利用SQL Server内置的STRING_SPLIT函数,将原表与拆分后的结果关联,这是最高效的集合式操作,完全不需要游标或复杂CTE:
DECLARE @input TABLE(id INT, words NVARCHAR(max)) INSERT INTO @input (id, words) VALUES (1, 'word1 word2 word3') , (2, 'word4 word5 word6') DECLARE @result TABLE(id INT, word NVARCHAR(50)) -- 直接插入结果,无需游标 INSERT INTO @result (id, word) SELECT i.id, ss.value FROM @input i CROSS APPLY STRING_SPLIT(i.words, ' ') ss WHERE ss.value <> '' -- 过滤可能的空字符串(如果原字段有连续空格)
这个方法的性能远优于游标,因为数据库引擎会以集合的方式处理所有数据,避免了逐行循环的开销,适合处理大量记录。
方法二:递归CTE(兼容SQL Server 2014及更早版本)
如果你的SQL Server版本不支持STRING_SPLIT,可以用递归CTE来实现拆分:
DECLARE @input TABLE(id INT, words NVARCHAR(max)) INSERT INTO @input (id, words) VALUES (1, 'word1 word2 word3') , (2, 'word4 word5 word6') DECLARE @result TABLE(id INT, word NVARCHAR(50)) ;WITH SplitCTE AS ( SELECT id, words, CAST('' AS NVARCHAR(50)) AS word, CHARINDEX(' ', words + ' ') AS space_pos FROM @input UNION ALL SELECT id, SUBSTRING(words, space_pos + 1, LEN(words)), SUBSTRING(words, 1, space_pos - 1), CHARINDEX(' ', SUBSTRING(words, space_pos + 1, LEN(words)) + ' ') FROM SplitCTE WHERE space_pos > 0 ) INSERT INTO @result (id, word) SELECT id, word FROM SplitCTE WHERE word <> '' -- 过滤空值 OPTION (MAXRECURSION 0) -- 如果拆分的单词数量超过100,需要设置这个选项
递归CTE通过逐层截取字符串中的单词来实现拆分,同样是集合式操作,性能比游标好很多。
内容的提问来源于stack exchange,提问作者Robert Dehmel
相关产品推荐
相关产品推荐

