Bra*_*adC 7 sql-server order-by window-functions sql-server-2017
所以我正在研究一个代码高尔夫拼图,需要在保持当前顺序的同时向结果添加一个 INT“数字”列n。
假设我的源数据是:
SELECT value
FROM STRING_SPLIT('one,two,three,four,five', ',')
Run Code Online (Sandbox Code Playgroud)
它以原始(所需)顺序返回项目:
value
-----
one
two
three
four
five
Run Code Online (Sandbox Code Playgroud)
如果我尝试使用ROW_NUMBER()
或RANK()
我被迫指定一个ORDER BY
,这value
是唯一合法的选择:
SELECT value, n = ROW_NUMBER() OVER(ORDER BY value)
FROM STRING_SPLIT('one,two,three,four,five',',')
Run Code Online (Sandbox Code Playgroud)
但这(如预期)按value
字母顺序排序,而不是按所需的原始顺序排列:
value n
------ ---
five 1
four 2
one 3
three 4
two 5
Run Code Online (Sandbox Code Playgroud)
连接到数字表不起作用,因为如果没有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
Run Code Online (Sandbox Code Playgroud)
但这真的很长很烦人。有什么更好的想法吗?
Joe*_*ish 10
该规范的方式做到这一点是:ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
。如果你在打高尔夫球,你可以尝试这样的事情:
SELECT value, n = ROW_NUMBER() OVER(ORDER BY (SELECT 1))
FROM STRING_SPLIT('one,two,three,four,five',',')
Run Code Online (Sandbox Code Playgroud)
它适用于您在问题中发布的简单案例:
我应该说,没有文件保证该ROW_NUMBER()
值将按照您期望的精确顺序排列。但它是代码高尔夫,所以这似乎已经足够了。
您不能依赖于按照原始字符串的顺序INSERT
生成IDENTITY
值。这可能是你观察到的,但这只是幸运的巧合,当然不能保证。
如果您没有重复项,以下将起作用:
DECLARE @str varchar(255) = 'one,two,three,four,five';
SELECT value, n = ROW_NUMBER() OVER
(ORDER BY CHARINDEX(',' + value + ',', ',' + @str + ','))
FROM STRING_SPLIT('one,two,three,four,five', ',')
ORDER BY n;
Run Code Online (Sandbox Code Playgroud)
对于代码高尔夫也许:
DECLARE @s char(99)='one,two,three,four,five';
SELECT value,n=RANK() OVER(ORDER BY CHARINDEX(','+value+',',','+@s+','))
FROM STRING_SPLIT('one,two,three,four,five', ',')ORDER BY n
Run Code Online (Sandbox Code Playgroud)
如果您有重复项,它会变得更加复杂。这里可能有一些想法:
另一种选择是使用序列:
DROP SEQUENCE IF EXISTS dbo.S;
CREATE SEQUENCE dbo.S START WITH 1;
SELECT value, NEXT VALUE FOR dbo.S
FROM STRING_SPLIT('one,two,three,four,five', ',');
Run Code Online (Sandbox Code Playgroud)
输出:
?????????????
? one ? 1 ?
? two ? 2 ?
? three ? 3 ?
? four ? 4 ?
? five ? 5 ?
?????????????
Run Code Online (Sandbox Code Playgroud)
STRING_SPLIT
在没有内置编号选项的情况下实现是很烦人的。在https://feedback.azure.com/forums/908035-sql-server/suggestions/32902852-string-split-is-not-feature-complete投票支持更改
归档时间: |
|
查看次数: |
5879 次 |
最近记录: |