10

私はこのテーブルに次のデータを入れました

Job    Quantity Status Repeat
1      100      OK     2
2      400      HOLD   0
3      200      HOLD   1
4      450      OK     3

各行の[繰り返し]列の値に基づいて、その行をもう一度繰り返す必要があります。たとえば、ジョブ1の場合、繰り返し値は2であるため、ジョブ1はさらに2回繰り返す必要があります。

結果のテーブルは次のようになります

Job    Quantity Status Repeat
1      100      OK     2
1      100      OK     2
1      100      OK     2
2      400      HOLD   0
3      200      HOLD   1
3      200      HOLD   1
4      450      OK     3
4      450      OK     3
4      450      OK     3
4      450      OK     3

誰かがこのクエリで私を助けてくれますか?

私はSQLサーバーを使用しています

4

4 に答える 4

13

これは、(私のシステム上の)個々のジョブに対して7,400回を超える繰り返しをサポートします。さらに必要な場合は、別のシステムテーブルまたはクロス結合を使用できます。

DECLARE @d TABLE (Job INT, Quantity INT, Status VARCHAR(12), Repeat INT);

INSERT @d SELECT 1, 100, 'OK'  ,2
UNION ALL SELECT 2, 400, 'HOLD',0
UNION ALL SELECT 3, 200, 'HOLD',1
UNION ALL SELECT 4, 450, 'OK'  ,3;

WITH x AS 
(
  SELECT TOP (SELECT MAX(Repeat)+1 FROM @d) rn = ROW_NUMBER() 
  OVER (ORDER BY [object_id]) 
  FROM sys.all_columns 
  ORDER BY [object_id]
)
SELECT * FROM x
CROSS JOIN @d AS d
WHERE x.rn <= d.Repeat + 1
ORDER BY Job;
于 2012-06-05T18:28:37.433 に答える
5
DECLARE @repeats TABLE
        (
        rn INT NOT NULL PRIMARY KEY
        );

WITH    q (rn, m) AS
        (
        SELECT  1, MAX(repeat) + 1
        FROM    jobs
        UNION ALL
        SELECT  rn + 1, m
        FROM    q
        WHERE   rn < m
        )
INSERT
INTO    @repeats
SELECT  rn
FROM    q

SELECT  j.*
FROM    jobs j
CROSS APPLY
        (
        SELECT  TOP (j.repeat + 1)
                NULL
        FROM    @repeats
        ) q (repeat)

可能な最大値よりも多くのレコードが保証されているテーブルがある場合は、代わりにそのテーブルをrepeat削除して使用できます。@repeats

于 2012-06-05T18:06:56.973 に答える
0

クエリを成功させるために外部データに依存せず、かなり簡単なので、以下のアプローチをお勧めします。Aaron Bertrandのコードを使用してデータテーブルを初期化しましたが、データを繰り返す方法に関する私のアプローチ-このアプローチでは、特定のテーブルに必要な再帰よりも多くの行を含める必要はなく、外部データに依存しません。

DECLARE @d TABLE (Job INT, Quantity INT, Status VARCHAR(12), Repeat INT);

INSERT @d SELECT 1, 100, 'OK'  , 2
UNION ALL SELECT 2, 400, 'HOLD', 0
UNION ALL SELECT 3, 200, 'HOLD', 1
UNION ALL SELECT 4, 450, 'OK'  , 3;

DECLARE @maxRecursion INT;
SET @maxRecursion = (SELECT MAX(Repeat) 
                       FROM @d);    

WITH Iterator AS 
(
    SELECT 1 AS Iterations
    UNION ALL
    SELECT Iterations + 1 FROM Iterator WHERE Iterations < @maxRecursion
)

SELECT A.*
  FROM @d AS A
 RIGHT JOIN Iterator ON Iterator.Iterations <= (A.Repeat + 1)
 ORDER BY Job ASC
OPTION (MAXRECURSION 0)

乾杯!

于 2017-07-13T18:12:54.287 に答える
-1

このクエリを(カーソルとして)実行するストアドプロシージャを記述してから、必要に応じて新しい一時テーブルに入力できます。

CREATE FUNCTION [dbo].[GetRepeatJobs]()
RETURNS 
@JobsRepeatTable TABLE (JobId int, JobName nchar(10))
AS
BEGIN
DECLARE @i int
DECLARE @j int
DECLARE @JobId int
DECLARE @JobName nchar(10)

DECLARE JobsCursor CURSOR FOR (select JobId, JobName, JobRepeat from jobs)
OPEN JobsCursor
FETCH NEXT FROM JobsCursor INTO @JobId, @JobName, @i

WHILE @@FETCH_STATUS = 0
BEGIN
    SELECT @j = 0
    WHILE @j < @i
    BEGIN
        INSERT INTO @JobsRepeatTable VALUES (@JobId, @JobName)
        SELECT @j = @j+1    
    END
    FETCH NEXT FROM JobsCursor INTO @JobId, @JobName, @i
END 
RETURN 
END

私にぴったりです。

于 2012-06-05T18:05:14.680 に答える