你能假设 string_split 函数的结果按顺序返回元素吗?总之,下面的代码正确吗?
DECLARE @tags NVARCHAR(400) = 'clothing,road,touring,bike'
DECLARE @FIRST nvarchar(100);
SELECT TOP 1 @FIRST = value
FROM STRING_SPLIT(@tags, ',');
Run Code Online (Sandbox Code Playgroud)
Aar*_*and 13
TOP 1没有ORDER BY不能保证返回即使输出相同的结果STRING_SPLIT()得到了保障(其中最绝的是不是)。虽然在实际使用中,您可能会发现很难提出数据未按顺序返回的反例,但这是一种可怕的做法。相信某样东西总是有效,因为你从未见过它坏掉,就像假设如果你在高速公路上放了一个鹿标志,那是你唯一能看到鹿的地方。
但是,让我们看看可以解决此问题的另一种方法。为什么我们不定位整个列表中每个单独字符串的位置:
DECLARE
@tags nvarchar(400) = N'clothing,road,touring,bike',
@c nchar(1) = N',';
SELECT value, CHARINDEX(@c + value + @c, @c + @tags + @c)
-- we surround the value and the string with leading/trailing ,
-- so that cloth isn't a false positive for clothing
FROM STRING_SPLIT(@tags, ',') AS t;
Run Code Online (Sandbox Code Playgroud)
这里的输出是:
你认为我们可以用它来确定列表中的第一个元素吗?当然!让我们再试一次:
DECLARE
@tags nvarchar(400) = N'clothing,road,touring,bike',
@first nvarchar(100),
@c nchar(1) = N',';
;WITH t AS
(
SELECT value, idx = CHARINDEX(@c + value + @c, @c + @tags + @c)
FROM STRING_SPLIT(@tags, ',')
)
SELECT TOP (1) @first = value FROM t ORDER BY idx;
PRINT @first;
Run Code Online (Sandbox Code Playgroud)
输出:
clothing
Run Code Online (Sandbox Code Playgroud)
您可以使用相同的逻辑来查找最后一个元素,只需将 更改ORDER BY idx为ORDER BY idx DESC。实际上,您可以使用此逻辑返回列表中的第 n 个字符串:
DECLARE
@tags nvarchar(400) = N'clothing,road,touring,bike',
@c nchar(1) = N',',
@nth tinyint;
SET @nth = 3;
;WITH t AS
(
SELECT value, idx = ROW_NUMBER() OVER
(ORDER BY CHARINDEX(@c + value + @c, @c + @tags + @c))
FROM STRING_SPLIT(@tags, ',')
)
SELECT * FROM t WHERE idx = @nth;
Run Code Online (Sandbox Code Playgroud)
结果:
touring
Run Code Online (Sandbox Code Playgroud)
作为免责声明,如果您有重复项,那将会把事情搞砸,因为索引值将始终代表该值在字符串中的第一次出现。您可以从ROW_NUMBER()to切换,DENSE_RANK()但这不能解决所有情况。你可以先去重复字符串(我在这里谈论一些边缘情况)。
Bre*_*zar 10
SQL Server 的 STRING_SPLIT 文档没有指定顺序保证。
有一个公开的反馈请求向 STRING_SPLIT 添加更多功能,包括排序,但截至本答案(2018 年中),状态只是“正在审查”。
目前,如果您需要保证输出顺序,请尝试其他字符串拆分技术。