You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server 2016及以上版本中,能否用STRING_SPLIT返回指定位置的值?

关于SQL Server中STRING_SPLIT的顺序与特定位置取值问题

咱们先把你的两个核心问题拆解开来回答:

1. STRING_SPLIT的结果顺序是否有保证?

这个得分版本看:

  • 在SQL Server 2016到2019版本中:官方明确说明,STRING_SPLIT返回的结果顺序是不固定、无保证的——哪怕你输入的字符串是按z_y_x这种明确顺序写的,输出的value列也可能乱序,完全不能依赖它的输出顺序来判断元素位置。
  • 在**SQL Server 2022(以及Azure SQL)**中:STRING_SPLIT新增了enable_ordinal参数,当你传入1时,函数会额外返回一个ordinal列,这个列严格对应元素在原字符串中的位置(比如z_y_x分割后,z的ordinal是1,y是2,x是3),此时顺序是100%可靠的。

2. 能否用STRING_SPLIT返回特定位置的值?

同样分版本处理:

针对SQL Server 2022+/Azure SQL

这就很简单了,直接用带enable_ordinal参数的STRING_SPLIT,过滤ordinal等于目标位置就行:

DROP TABLE IF EXISTS #split
SELECT 'z_y_x' AS splitIt INTO #split
UNION SELECT 'a_b_c'

-- 提取每个字符串的第2个元素
SELECT s.splitIt, ss.value
FROM #split s
CROSS APPLY STRING_SPLIT(s.splitIt, '_', 1) ss
WHERE ss.ordinal = 2

执行后会得到z_y_x对应的y,a_b_c对应的b,完全符合预期。

针对SQL Server 2016-2019

因为这个版本的STRING_SPLIT没有位置列,而且顺序无保证,你原来用ROW_NUMBER()的方法其实有问题——你在窗口函数里写ORDER BY s.splitIt,但同一个splitIt的所有分割行,这个排序字段是完全一样的,数据库会随机分配行号,根本没法对应真实的元素位置。

推荐用OPENJSON来替代,它在处理字符串拆分时会严格保留原顺序,而且是2016版本就支持的:

DROP TABLE IF EXISTS #split
SELECT 'z_y_x' AS splitIt INTO #split
UNION SELECT 'a_b_c'

-- 提取每个字符串的第2个元素(OPENJSON的key从0开始,所以+1对应第2位)
SELECT s.splitIt, oj.value
FROM #split s
CROSS APPLY OPENJSON('["' + REPLACE(s.splitIt, '_', '","') + '"]') oj
WHERE CAST(oj.[key] AS INT) + 1 = 2

这个方法的原理是把原字符串转成JSON数组,OPENJSON会给每个元素分配从0开始的key,对应原字符串的顺序,所以过滤key+1就能拿到指定位置的元素。

当然你也可以用SUBSTRING+CHARINDEX的组合来写自定义函数,但OPENJSON的写法更简洁通用。


内容的提问来源于stack exchange,提问作者Stagg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:04:36