我需要创建一个从1到n的范围编号
例如,参数为@StartingValue
@StartingValue int = 96
然后结果应该是:
Number
-------------
96
95
94
93
92
ff.
1
有没有人知道如何做到这一点?
谢谢。
答案 0 :(得分:4)
使用Tally Table生成数字:
DECLARE @N INT = 96
;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(@N) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E8
)
SELECT * FROM CteTally ORDER BY N DESC
Jeff的文章(上面链接)的解释:
CTE称为E1(如10E1中的科学记法)仅此而已 只有十个SELECT 1作为单个结果集返回。
E2与自己进行E1的CROSS JOIN。这会返回一个结果 一组10 * 10或最多100行。我说"直到"因为如果TOP 功能是100或更少,CTE是"智能"足以知道它 实际上并不需要更进一步,E4和E8甚至不会来 发挥作用。如果TOP的值小于100,则不是全部100行 E2有能力制作。它总能做到 足够根据TOP功能。
你可以从那里开始。 E4是E2的CROSS JOIN并将弥补 到100 * 100或10,000行,E8是E4的CROSS JOIN 比大多数人需要更多的行。如果你确实需要更多,那么 只需添加一个E16作为E8的CROSS JOIN并更改最终的FROM子句 来自E16。
这个坏孩子的真正惊奇之处在于产生了零 READS 即可。绝对没有,纳达,没有。
答案 1 :(得分:2)
一个简单的方法是数字表。对于合理的数字(最高为数千),您可以使用spt_values
:
with numbers as (
select top 96 row_number() over (order by (select null)) as n
from t
)
. . .
另一种方法是递归CTE:
with numbers as (
select 96 as n
union all
select n - 1
from numbers
where num > 1
)
对于较大的值,您需要使用MAXRECURSION
选项。
答案 2 :(得分:0)
另一种方式。
SELECT N.number FROM
master..spt_values N
WHERE
N.type = 'P' AND
N.number BETWEEN 1 AND 96
ORDER BY N.number DESC
有关spt_values
What is the purpose of system table master..spt_values and what are the meanings of its values?
答案 3 :(得分:0)
Sequance of no's can be generated by following ways: 1. Using row_number by querying a large table and get the sequance. 2. Using system tables as you can see other people comments. 3. Using recursive CTE. declare @maxValue int = 96 ; WITH rangetest AS ( SELECT MinValue = @maxValue UNION ALL SELECT MinValue = MinValue - 1 FROM rangetest WHERE MinValue > 1 ) SELECT * from rangetest OPTION (MAXRECURSION 0)