2016-09-20 11 views
0

SQL Serverテーブルに特定の数の行を挿入する必要があります。数値の範囲に基づいてテーブルに複数の行を挿入する方法

DECLARE @val AS INT = 20, 
     @val2 AS VARCHAR(50), 
     @Date AS DATETIME = CONVERT(DATETIME,'02-05-2016'), 
     @i AS INT = 0 

SET @val2 = 'abc' 

DECLARE @tbl TABLE 
(
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [val2] VARCHAR(50) NULL, 
    [datum] [datetime] NULL 
) 

--INSERT INTO @tbl 
SELECT @val2, DATEADD(DAY, @i, @Date) 
UNION ALL 
SELECT @val2, DATEADD(DAY, @i, @Date) 

このクエリでは、指定された日付から変数 '@val'に割り当てられた値の数までの日付を挿入する必要があります。したがって、この場合、'02 -05-2016 'から始まる20個の行をテーブルに挿入し、各行に対して1日増やす必要があります。

ループ処理や複数の挿入文を使用せずに単一の文でどのように行うことができますか?

+0

明らかに実行中の数字/日付のリストを作成しようとしています。[私の回答の1つで](http://stackoverflow.com/a/32474751/5089204)には、「Tally-CTE」を使った例があります数字、日付、および毎日の多くの副情報のリストを作成します。これがあなたが必要とするものだと思ってください... – Shnugo

答えて

1

数値テーブルがある場合はそれを使用できます。値が2048までのテーブルを使用する場合はmaster.dbo.spt_valuesを使用するか、独自のテーブルを作成します。このケースでは、master.dbo.spt_valuesを使用することができます。

DECLARE @val AS INT=20, @val2 AS VARCHAR(50); 
DECLARE @Date AS DATETIME = CONVERT(DATETIME,'02-05-2016'); 

SET @val2 = 'abc' 

INSERT INTO dbo.YourTable 
SELECT @val2, DATEADD(DAY,number,@Date) 
FROM master.dbo.spt_values 
WHERE type = 'P' 
AND number <= @val; 

これはゼロから始まるので、けれども、あなたは私が私のコメントで指さ詳細な回答のほかに、結果

+0

これは最も速く最も実現可能な解決策です。ありがとうございます。 –

0

として21行を取得します、これは短い考え方:

DECLARE @start INT=0; 
DECLARE @end INT=19; --0 to 19 are 20 days 

DECLARE @StartDate DATE={d'2016-01-01'}; 

--Create a List of up to 1.000.000.000 rows on the fly 
--This is limited by start and end parameter 

;WITH x AS(SELECT 1 AS N FROM(VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) AS tbl(N))--10^1 
,N3 AS (SELECT 1 AS N FROM x CROSS JOIN x AS N2 CROSS JOIN x N3) --10^3 
,Tally AS(SELECT TOP(@[email protected] +1) ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) + @start -1 AS Nr FROM N3 
      CROSS JOIN N3 N6 CROSS JOIN N3 AS N9) 

--INSERT INTO your_table 

SELECT @val2 --your @val2 here as a constant value 
     ,DATEADD(DAY,Nr,@StartDate) 
FROM Tally 
0

recursive CTEを使用できます。

DECLARE @i INT = 1 
    , @m INT = 19 
    , @d DATETIME2 = '2016-05-02'; 

WITH i AS (
    SELECT 0 AS increment 
    UNION ALL 
    SELECT i.increment + @i 
    FROM i 
    WHERE i.increment < @m 
) 
SELECT i.increment 
    , DATEADD(DAY, i.increment, @d) 
FROM i 
OPTION (MAXRECURSION 100); 

は必須ではありませんが、私はそれがどのように動作するかを説明するために、それが含まれている下、でOPTION (MAXRECUSION 100)ヒントに注意してください。デフォルトでは、このメソッドを使用した結果は100件に制限されています。したがって、このステートメントを使用しない場合は、@mが大きい数値です。 1000 SQLはエラーを生成します。あなたは無制限を意味する0に設定することができますが、コードをテストした後でのみ無限ループに陥る可能性があります(これがデフォルトで存在します)。

+0

これは近代的な、セットベースの方法です*は、「クロスジョイン」アプローチよりも約3-5倍遅いです。再帰的なCTEは隠されたRBARです。彼らは木を下ろすのは素晴らしいですが、実行中のリストを作成するための最良のツールではありません。 – Shnugo

+0

@Shnugoそこには余分な形容詞が削除されています – knuckles

関連する問題