2016-04-06 6 views
1


SQLでnから1の範囲を作成する

1からnの範囲番号を作成する必要があります。

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

誰もがこれを行うにはどのようなアイデアを持っています:?たとえば、パラメータは、結果がどうあるべき@StartingValue

@StartingValue int = 96 


ですか
ありがとうございます。

+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 

詳細【ループなしのセットまたはシーケンスを生成](http://sqlperformance.com/2013/01/t-sql-queries/generate-a- set-1) –

答えて

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 

説明:

CTEは、(科学表記について10E1のように)E1と呼ば何もない 10個のSELECT 1が1つの結果セットとして返されます。

E2はそれ自身でE1のクロスジョインを行います。その結果、単一の結果 が10 * 10または最大100行に設定されます。 TOP の機能が100以下であれば、CTEは実際には はそれ以上行く必要はなく、E4とE8は来なくても になることを知るのに十分なほどスマートです。 。 TOPに100未満の値がある場合、E2が作成できるすべての100行である が作成されるわけではありません。 TOP機能によれば、常に になります。

そこからフォローできます。 E4はE2のクロスジョインであり、 を100 * 100または10,000行に構成し、E8はE4のクロスジョインであり、多くの人が必要とするよりも多くの行を にすることになります。さらに必要があれば、 はE8のCROSS JOINとしてE16を追加し、最後のFROM句 をFROM E16に変更するだけです。

この悪い男の子について本当に驚くべきことは、は、ゼロ のREADSです。絶対に何もない、nada、nil。

2

単純な方法の1つが数値表です。もう一つの方法は、再帰CTEである

with numbers as (
     select top 96 row_number() over (order by (select null)) as n 
     from t 
    ) 
. . . 

:(ロー数千人まで)合理的な数について、あなたはspt_valuesを使用することができ、より大きな値について

with numbers as (
     select 96 as n 
     union all 
     select n - 1 
     from numbers 
     where num > 1 
    ) 

、あなたはMAXRECURSIONを使用する必要がありますオプション。

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) 
関連する問題