2011-12-21 11 views
2

は、私はこのようなデータのセットを持っている範囲の間の手順で番号を取得するにはSQLクエリは

2500 
2510 
2520 
2530 
2540 
2550 
2560 
2570 
2580 
2590 
2600 
2610 
2620 
2630 
2640 
2650 
2660 
2670 
2680 
2690 
2700 

私はこれがwhileループを使用して実現できることを認識しています。 Common Table Expressions(必要に応じて)を使用して選択クエリを使用してこれを実行できるかどうかを教えてください。前もって感謝します。

答えて

4

数値表(またはmaster..spt_values)を使用できます。

declare @MinNo int 
declare @MaxNo int 
declare @IncrementStep int 

set @MinNo = 2500 
set @MaxNo = 2700 
set @IncrementStep = 10 

select @MinNo + Number * @IncrementStep 
from master..spt_values 
where type = 'P' and 
     number between 0 and (@MaxNo - @MinNo)/@IncrementStep 

または再帰CTE

;with C as 
(
    select @MinNo as Num 
    union all 
    select Num + @IncrementStep 
    from C 
    where Num < @MaxNo 
)  
select Num 
from C 
+0

Jeff Modenについて話をすると、再帰的なCTEがおそらくこのタイプの問題の良い解決策にはならない理由を説明した回答があります:http://stackoverflow.com/questions/10819/sql-auxiliary-table-of-numbersしかし、やはり、最高のパフォーマンスを発揮するソリューションは、常に物理数値テーブルを使用することです) – Tao

1

@Mikaelエリクソンはすでに(オンラインでの検索数のテーブル/集計テーブルを述べ、がたくさんある

CREATE FUNCTION [dbo].[Sequence](@min INT, @max INT, @step INT) 
RETURNS @ret TABLE (id INT PRIMARY KEY) 
AS 
BEGIN 
    WITH numbers(id) as 
    (
     SELECT @min id 
     UNION ALL 
     SELECT [email protected] 
     FROM numbers 
     WHERE id < @max 
    ) 
    INSERT @ret 
    SELECT id FROM Numbers 
    OPTION(MAXRECURSION 0) 
    RETURN 
END 
1

この便利な機能を参照してください。多くのDBAは、自分が管理しているどのシステムにもタリー表が存在することを常に望んでいる)

I ju先日私がオンラインで見た非再帰CTEベースの「集計表」ソリューションを共有したいと思っていました。データベースの依存関係がなくても巨大な範囲(4億文字の論理行)と一般的なアプリケーションで驚くほどエレガントだと思います。

WITH 
     E00(N) AS (SELECT 1 UNION ALL SELECT 1), 
     E02(N) AS (SELECT 1 FROM E00 a, E00 b), 
     E04(N) AS (SELECT 1 FROM E02 a, E02 b), 
     E08(N) AS (SELECT 1 FROM E04 a, E04 b), 
     E16(N) AS (SELECT 1 FROM E08 a, E08 b), 
     E32(N) AS (SELECT 1 FROM E16 a, E16 b), 
    cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32) 
SELECT * 
FROM cteTally 
WHERE N >= 2500 
    AND N <= 2700 
    AND N % 10 = 0 

hereが見つかりましたが、それがこのCTEの元のソースかどうかはわかりません。

分かりやすい点は、最小、最大、またはステップサイズを気にする必要がなく、ほとんどの(1回限りの)状況で非常にうまくいくことです。つまり、頻繁に呼び出されるビジネスプロセスでは使用しないでください。物理的なインデックス番号のテーブルは、常により優れたパフォーマンスを発揮します。

EDIT:このメソッドのソースについてもう少し調べました(私が参照した記事のstackoverflowリンクを見逃していました)。それは当初、Itzik Ben-Ganに起因していました。 「Inside Microsoft SQL Server 2005 - T-SQL Querying」(says Jeff Moden、私が暗黙のうちに信頼する人)の本です。