在 SQL 中创建从 n 到 1 的范围

问题描述 投票:0回答:4


我需要创建一个从 1 到 n 的范围数字。
例如参数为

@StartingValue

@StartingValue int = 96

那么结果应该是:

Number
-------------
96
95
94
93
92
ff.
1

有人知道如何做到这一点吗?
谢谢你。

sql sql-server t-sql sql-server-2008-r2
4个回答
5
投票

使用 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 出发。

这个坏男孩真正令人惊奇的是 产生零 阅读。绝对没有,无,无。


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
选项。


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
系统表master..spt_values的用途是什么以及其值的含义是什么?


0
投票
no的序列可以通过以下方式生成:
1. 使用 row_number 查询大表并获取序列。
2.使用系统表,因为你可以看到其他人的评论。
3.使用递归CTE。

声明@maxValue int = 96

;带范围测试 AS
(
    选择最小值 = @maxValue
    联合所有
    选择最小值 = 最小值 - 1
    FROM 范围测试
    其中最小值 > 1
)
选择  *
来自范围测试
选项(最大递归0)
© www.soinside.com 2019 - 2024. All rights reserved.