Following query will return 1-10 in 10 rows.
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
But when I set @Range as 10000 it returns 7374 rows. Why this query can't return more than 7374 rows.
UPDATE
I just found another way to achieve my requirement as following
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);
Without last line of code it breaks with error Maximum recursion 100 has been exhausted before statement completion and I found this line is specifying 0 for infinite recursion. But this query seems a little slower to me. Is there any faster way???
when value in variable exceeds value 7374, that doesn't matter. That table has only 7374 rows.
As commented earlier, it's because you reached the number of rows of
sys.columns
. Here is another way to generate list of numbers or what others callNumbers Table
orTally Table
.This uses cascaded
CTE
s and is said to be the fastest way to create a Tally Table:You could easily add another CTE if you need more than 10,000 rows.
For more information about Tally Table, read this excellent article by Jeff Moden.
For performance comparisons among ways to generate Tally Tables, read this.
Explanation taken from Jeff's article:
It is because the maximum number of row are 7374, you can use the master..spt_Values table for that cross join to itself and you would get
6325225
values for your desiredDuration
column.One way to generate a large series of numbers would be to use a
cross join
to create a cartesian product between two tables which will generate a set that isn^2
in size.This approach however performs a lot worse than the solution put forward in the answer by Felix Pamittan and therefore shouldn't be used.
This would generate a set of 54375876 rows in your case. Instead of generating the rows on the fly you should consider creating a tally table suitable for your needs.
It means that the total number of rows return for your query is 7374. If you can create some tables and run the code, you will see the increase in the number
I use this function to get running numbers. You can directly use it in FROM (or with JOIN or APPLY...)
After reading other comments I changed this to the "stacked CTE" approach (thx to Felix)