在SQL Server中选择N行

Est*_*sty 2 sql t-sql sql-server

以下查询将在10行中返回1-10.

DECLARE @Range AS INT = 10

;WITH CTE AS(
    SELECT TOP (@Range) Duration = ROW_NUMBER() OVER(ORDER BY OBJECT_ID)
    FROM sys.all_columns
    ORDER BY [Object_id]
)
SELECT Duration from CTE
Run Code Online (Sandbox Code Playgroud)

但是当我将@Range设置为10000时,它返回7374行.为什么此查询不能返回超过7374行.

UPDATE

我刚刚找到另一种方法来实现我的要求如下

DECLARE @start INT = 1;
DECLARE @end INT = 10;

WITH numbers AS (
    SELECT @start AS number
    UNION ALL
    SELECT number + 1 
    FROM  numbers
    WHERE number < @end
)
SELECT *
FROM numbers
OPTION (MAXRECURSION 0);
Run Code Online (Sandbox Code Playgroud)

如果没有最后一行代码则会出现错误.在语句完成之前,最大递归100已经用完了,我发现此行为无限递归指定了0.但这个查询对我来说似乎有点慢.有没有更快的方法???

Fel*_*tan 12

如前所述,这是因为你达到了行数sys.columns.这里是另一种方式来生成数字或其他所谓的名单Numbers TableTally Table.

这使用级联CTEs,据说是创建Tally表的最快方法:

DECLARE @Range AS INT = 7374

;WITH E1(N) AS( -- 10 ^ 1 = 10 rows
    SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
E8(N) AS(SELECT 1 FROM E4 a CROSS JOIN E4 b), -- 10 ^ 8 = 10,000,000 rows
CteTally(N) AS(
    SELECT TOP(@Range) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
    FROM E8
)
SELECT * FROM CteTally
Run Code Online (Sandbox Code Playgroud)

如果需要超过10,000行,您可以轻松添加另一个CTE.

有关Tally Table的更多信息,请阅读Jeff Moden 撰写的这篇优秀文章.

有关生成Tally表的方法之间的性能比较,请阅读此内容.


杰夫的文章解释:

被称为CTE E1(如10E1中的科学记法)仅仅是十个SELECT 1单独的结果集.

E2做了CROSS JOINE1自身.返回单个结果集10*10或最多100行.我说的"达人",因为如果TOP功能是100或以下,热膨胀系数的是"聪明",足以知道,它实际上并不需要再往前走,并E4E8甚至不会开始发挥作用.如果TOP值小于100,则不会生成所有100行E2.根据TOP功能它总是足够的.

你可以从那里开始.E4CROSS JOINE2,并会高达100*100或10,000行,E8CROSS JOINE4 ,这将使比大多数人永远都需要更多的行.如果你需要更多的,则只需添加一个E16作为CROSS JOINE8,改变的最终FROM子句FROM E16.

这个坏孩子真正令人惊讶的是,它会产生零读数.绝对没有,纳达,没有.