我需要创建一个从 1 到 n 的范围数字。
例如参数为
@StartingValue
@StartingValue int = 96
那么结果应该是:
Number
-------------
96
95
94
93
92
ff.
1
有人知道如何做到这一点吗?
谢谢你。
使用 Jeff Moden 的 计数表 生成数字:
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 = 100,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
摘自杰夫文章的解释(上面链接):
称为 E1 的 CTE(如科学记数法的 10E1)仅此而已 超过 10 个 SELECT 1 作为单个结果集返回。
E2 与自身进行 E1 的 CROSS JOIN。返回单个结果 一组 10*10 或最多 100 行。我说“最多”是因为如果顶部 函数是 100 或更少,CTE 足够“聪明”,知道它 实际上不需要再进一步,E4和E8甚至不会来 进入游戏。如果 TOP 的值小于 100,则不是所有 100 行 E2有能力制造的东西将会制造出来。它总是会让 根据TOP函数就够了。
您可以从那里关注。 E4 是 E2 的 CROSS JOIN,将弥补 到 100*100 或 10,000 行,E8 是 E4 的交叉联接,这将使 比大多数人需要的行数还要多。如果您确实需要更多,那么 只需添加 E16 作为 E8 的 CROSS JOIN 并更改最后的 FROM 子句 从 E16 出发。
这个坏男孩真正令人惊奇的是 产生零 阅读。绝对没有,无,无。
一种简单的方法是数字表。对于合理的数字(最多数千),您可以使用
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
选项。
还有另一种方式。
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
系统表master..spt_values的用途是什么以及其值的含义是什么?
no的序列可以通过以下方式生成: 1. 使用 row_number 查询大表并获取序列。 2.使用系统表,因为你可以看到其他人的评论。 3.使用递归CTE。 声明@maxValue int = 96 ;带范围测试 AS ( 选择最小值 = @maxValue 联合所有 选择最小值 = 最小值 - 1 FROM 范围测试 其中最小值 > 1 ) 选择 * 来自范围测试 选项(最大递归0)