所以我正在研究一个代码高尔夫拼图,需要在结果中添加一个 INT“数字”列n,同时保持当前顺序。
假设我的源数据是:
SELECT value
FROM STRING_SPLIT('one,two,three,four,five', ',')
它以原始(所需)顺序返回项目:
value
-----
one
two
three
four
five
如果我尝试使用ROW_NUMBER()
或者RANK()
我被迫指定一个ORDER BY
,这value
是唯一合法的选择:
SELECT value, n = ROW_NUMBER() OVER(ORDER BY value)
FROM STRING_SPLIT('one,two,three,four,five',',')
但这(如预期的那样)按value
字母顺序排序,而不是按所需的原始顺序排列:
value n
------ ---
five 1
four 2
one 3
three 4
two 5
加入数字表是行不通的,因为没有WHERE
子句我会得到一个完整的外连接。
我能想到的最好的方法是使用带有标识字段的临时表:
CREATE TABLE #argg (n INT IDENTITY(1,1), v VARCHAR(99))
INSERT #argg
SELECT value v
FROM STRING_SPLIT('one,two,three,four,five',',')
SELECT *
FROM #argg
DROP TABLE #argg
但这真的很长而且很烦人。有更好的想法吗?
执行此操作的规范方法如下
ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
:如果你在打高尔夫球,你可以尝试这样的事情:它适用于您在问题中发布的简单案例:
我应该说,没有文件保证该
ROW_NUMBER()
值将按照您期望的精确顺序。但这是代码高尔夫,所以这似乎已经足够好了。您不能依赖您
INSERT
按原始字符串的顺序生成IDENTITY
值。这可能是你观察到的,但这只是幸运的巧合,当然不能保证。如果您没有重复项,以下将起作用:
对于代码高尔夫也许:
如果你有重复,它变得更加复杂。这里的一些想法可能是:
另一种选择是使用序列:
输出:
STRING_SPLIT
在没有内置编号选项的情况下实现令人讨厌。在https://feedback.azure.com/forums/908035-sql-server/suggestions/32902852-string-split-is-not-feature-complete投票支持更改只需从您的问题中添加另一种选择。但我认为不能保证订购,