次の列(開始、終了、間隔)を持つテーブルがあるとしましょう
Start と End の間のすべての値を、それぞれ 1 行の間隔で取得する方法はありますか? (開始、終了、間隔) テーブルの複数の行になりますが、それらは重複してはいけません。
可能であれば、ループ/カーソル/一時テーブル/変数テーブルなしで。
サンプルデータ
開始終了間隔 1 3 1 9 12 1 16 20 2
望ましい結果:
結果 1 2 3 9 10 11 12 16 18 20
次の列(開始、終了、間隔)を持つテーブルがあるとしましょう
Start と End の間のすべての値を、それぞれ 1 行の間隔で取得する方法はありますか? (開始、終了、間隔) テーブルの複数の行になりますが、それらは重複してはいけません。
可能であれば、ループ/カーソル/一時テーブル/変数テーブルなしで。
サンプルデータ
開始終了間隔 1 3 1 9 12 1 16 20 2
望ましい結果:
結果 1 2 3 9 10 11 12 16 18 20
これは、再帰的な共通テーブル式の優れた使用例です。
;with cte as (
select [Start] as Result, [End], [Interval]
from Table1
union all
select Result + [Interval], [End], [Interval]
from cte
where Result + [Interval] <= [End]
)
select Result
from cte
order by Result
あなたはこのようにすることができます
WITH tally AS (
SELECT 0 n
UNION ALL
SELECT n + 1 FROM tally WHERE n < 100 -- adjust 100 to a max possible value for (end - start) / interval
)
SELECT start + n * [interval] result
FROM Table1 t CROSS JOIN tally n
WHERE n.n <= (t.[end] - t.start) / t.[interval]
ORDER BY result
注:このようなクエリを多数実行する場合は、再帰 CTEを列の主キーを持つtally
永続的な数値テーブルに置き換えることを検討してください。tally
n
出力:
| | 結果 | |--------| | | 1 | | | 2 | | | 3 | | | 9 | | | 10 | | | 11 | | | 12 | | | 16 | | | 18 | | | 20 |
これがSQLFiddleのデモです
私はあなたが答えを受け入れたことを知っています。これも正しいと思います。
select x.number
from master..spt_values x cross join table1 t
where x.type='p' and x.number between t.[start] and t.[end]
and x.number % t.[interval] = 0
結果:
| NUMBER |
|--------|
| 1 |
| 2 |
| 3 |
| 9 |
| 10 |
| 11 |
| 12 |
| 16 |
| 18 |
| 20 |
編集:無制限の数にしたい場合は、このアプローチを試して、必要に応じてさらに数字のテーブルをクロス結合してください。この例は 9999 まで上がります。
;WITH Digits AS (
select Digit
from ( values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9))
AS t(Digit))
,Numbers AS (
select u.Digit + t.Digit*10 + h.Digit*100 + th.Digit*1000 as number
from Digits u
cross join Digits t
cross join Digits h
cross join Digits th
--Add more cross joins as required
)
Select number
From Numbers x cross join table1 t
where x.number between t.[start] and t.[end]
and x.number % t.[interval] = 0;
Order by number