2011-03-11 72 views
4

我正在研究一个函数,该函数将参数的数目和数目都设为低,并返回一个包含(和包含)之间所有内容的表。在sql server中生成一个序列

我知道我可以使用游标并增加一个变量,每次迭代都会将它添加到基于范围的表中,但是如果可能的话,我宁愿避免游标。有没有其他人有一个方法来做到这一点的建议? (当我输入这个即时通讯思维可能是一个CTE,我将去调查)。

+0

SQL服务器2011( “德纳”)将具有[适当的序列](http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/a-first-look-at-sequences-in -sql-server)当它出来时... –

+0

@marc_s - 它们可以用作adhoc辅助数字表吗? –

回答

2

只需创建一个带索引的永久辅助数字表并完成它。这将执行任何其他方法。

See Jeff Moden's answer here for more details和用于填充这样的表的脚本。如果由于某种原因,这不是一个选项,根据链接答案中的性能测试,这应该击败递归CTE。

WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1), 
     E02(N) AS (SELECT 1 FROM E00 a, E00 b), 
     E04(N) AS (SELECT 1 FROM E02 a, E02 b), 
     E08(N) AS (SELECT 1 FROM E04 a, E04 b), 
     E16(N) AS (SELECT 1 FROM E08 a, E08 b), 
     E32(N) AS (SELECT 1 FROM E16 a, E16 b), 
    cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32) 
    SELECT N FROM cteTally 
    WHERE N BETWEEN 10 AND 20 
+0

我正在寻找相当于PostgreSQL generate_series()。首先,我尝试了递归CTE,但与此相比,它有1M记录的时间滞后。 – Waqar

4

是的,你可以用recursive CTE来做到这一点。例如,要生成10和20之间的数字:

WITH f AS 
(
    SELECT 10 AS x 
    UNION ALL 
    SELECT x + 1 FROM f WHERE x < 20 
) 
SELECT * FROM f 
+0

非常好的解决方案。谢谢! – Kyle

+1

伟大的解决方案,但请注意,默认情况下,结果的最大数目设置为100,并且您可以使用OPTION(maxrecursion 32767)将其增加到32767; – pcofre

+1

@pcofre - 您可以使用'OPTION(MAXRECURSION 0)'来实现无限制,但性能可能会成为问题。 –