如何将T-SQL中连字符分隔的字符串按位置拆分为列?
合适的T-SQL拆分解决方案
方案1:使用STRING_SPLIT(SQL Server 2022+ 或 Azure SQL)
SQL Server 2022及之后版本的STRING_SPLIT支持enable_ordinal参数,能返回拆分后每个元素的位置序号,完美匹配需求,代码简洁逻辑清晰:
SELECT Record, col1 = MAX(CASE WHEN ordinal = 1 THEN value END), col2 = MAX(CASE WHEN ordinal = 2 THEN value END), col3 = MAX(CASE WHEN ordinal = 3 THEN value END), col4 = MAX(CASE WHEN ordinal = 4 THEN value END), col5 = MAX(CASE WHEN ordinal = 5 THEN value END), col6 = MAX(CASE WHEN ordinal = 6 THEN value END), col7 = MAX(CASE WHEN ordinal = 7 THEN value END), col8 = MAX(CASE WHEN ordinal = 8 THEN value END) FROM Table1 CROSS APPLY STRING_SPLIT(StringValue, '-', 1) -- 第三个参数1启用ordinal返回 GROUP BY Record ORDER BY Record;
说明:
STRING_SPLIT的第三个参数1会返回ordinal列,代表每个拆分元素在原字符串中的位置(从1开始)- 用
CASE配合MAX聚合,将对应位置的元素映射到col1-col8,空位置自然返回NULL
方案2:使用OPENJSON(兼容SQL Server 2016+)
如果你的SQL Server版本低于2022,可以用OPENJSON处理,先将原字符串转换为JSON数组格式:
SELECT Record, col1 = JSON_VALUE(json_arr, '$[0]'), col2 = JSON_VALUE(json_arr, '$[1]'), col3 = JSON_VALUE(json_arr, '$[2]'), col4 = JSON_VALUE(json_arr, '$[3]'), col5 = JSON_VALUE(json_arr, '$[4]'), col6 = JSON_VALUE(json_arr, '$[5]'), col7 = JSON_VALUE(json_arr, '$[6]'), col8 = JSON_VALUE(json_arr, '$[7]') FROM Table1 CROSS APPLY ( SELECT '["' + REPLACE(StringValue, '-', '","') + '"]' AS json_arr ) AS j;
说明:
- 通过
REPLACE把连字符分隔的字符串转成JSON数组格式(比如422100----130转成["422100","","","","130","","",""]) - 用
JSON_VALUE按数组索引提取对应位置的值,空位置会返回NULL
原PARSENAME方案失效原因
PARSENAME原本用于解析对象名(如数据库.架构.表.列),它的行为导致无法满足需求:
- 从右往左计数,和你需要的从左往右的位置逻辑相反
- 连续的点会被视为单个分隔符,空位置被直接跳过,无法正确对应col1-col8的位置
比如REPLACE("422100----130", '-', '.')得到422100....130,PARSENAME会把它识别为2个部分而非5个,最终结果错位且空值丢失。
内容的提问来源于stack exchange,提问作者Stetson Reed
相关产品推荐
相关产品推荐

