SQL Server 2018使用STRING_SPLIT搭配ORDER BY返回结果矛盾问题求解
异常成因
你遇到的结果不一致并非SQL Server的BUG,是两个原因共同导致的:
- 你使用了
VALUE字段作为排序依据,排序逻辑本身就不符合取拆分首项的需求:
字符串排序规则下,数字字符的ASCII码远小于大写英文字符:- 第一组拆分结果为
AgingFactorCorr、25,按VALUE升序排序时25排在首位,所以取第一行返回值 - 第二组拆分结果为
AlarmBuzSignal、NA,按VALUE升序排序时首字母为A的字符串排在首位,所以取第一行返回键
- 第一组拆分结果为
- SQL Server 2022之前的
STRING_SPLIT函数官方不保证返回顺序和输入子串的顺序一致,你直接执行前两条语句看到的"先返回键后返回值"属于不可靠的偶然表现,无法作为逻辑依据。
更合理的键值对取键方案
方案1:字符串直接截取(全版本兼容,性能最优)
键值对的键固定是第一个冒号之前的内容,不需要拆分整个字符串,直接用字符串函数截取即可,兼容性最好、执行效率最高:
-- 基础写法,适配有冒号的场景 SELECT LEFT( 待拆分字段, CHARINDEX(':', 待拆分字段) - 1 ) AS 键 FROM 表名 -- 兼容无冒号的场景,没有冒号时返回完整字符串 SELECT IIF( CHARINDEX(':', 待拆分字段) > 0, LEFT(待拆分字段, CHARINDEX(':', 待拆分字段) - 1), 待拆分字段 ) AS 键 FROM 表名
方案2:带顺序的拆分(适配SQL Server 2022、Azure SQL)
如果使用的是SQL Server 2022及以上版本、或者Azure SQL,可以直接开启STRING_SPLIT的enable_ordinal参数,返回的ordinal字段就是子串在原字符串中的顺序,直接筛选ordinal = 1即可取到键:
SELECT value AS 键 FROM STRING_SPLIT(待拆分字段, ':', 1) WHERE ordinal = 1
内容的提问来源于stack exchange,提问作者Arthur
相关产品推荐
相关产品推荐

