2011-07-07 9 views
6

私はマスターオブジェクトのいくつかの子を持つテーブルを持っています。どれでも子供が複数回発生する可能性があり、その番号が含ま発生箇所の欄があり、そのテーブル内のデータのようなものです:それぞれの子で、同じ行を複数回選択する

ChildID | ParentID | Occurences 
------------------------------- 
     1 |  1 |  2 
     2 |  1 |  2 
     3 |  2 |  1 
     4 |  2 |  3 

私は、すべての子のリストを取得する必要があります以下のような結果に倍のcorect数を表示されて、何か

IDENT | ChildID | ParentID 
-------------------------- 
    1 |  1 |  1 
    2 |  1 |  1 
    3 |  2 |  1 
    4 |  2 |  1 
    5 |  3 |  2 
    6 |  4 |  2 
    7 |  4 |  2 
    8 |  4 |  2 
私はテーブルをループし、neccessary限り多くの行を挿入し、カーソルでこれを行うことができますが、私はそれが最善の解決策であるとは思わない

可能。助けのための

おかげで


作成スクリプトが含ま:

DECLARE @Children TABLE (ChildID int, ParentID int, Occurences int) 

INSERT @Children 
SELECT 1, 1, 2 UNION ALL 
SELECT 2, 1, 2 UNION ALL 
SELECT 3, 2, 1 UNION ALL 
SELECT 4, 2, 3 
+1

なぜあなたはこれを行う必要があるのか​​尋ねますか?多分、同じ行を何度か選択するよりも良い方法があります。 – EdoDodo

+0

異なる可能性があるいくつかの余分なデータがあるので、それぞれの子の行を生成する必要があります。 – SWeko

答えて

7
;with C as 
(
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from @Children 
    union all 
    select ChildID, 
     ParentID, 
     Occurences - 1 as Occurences 
    from C 
    where Occurences > 0 
) 
select row_number() over(order by ChildID) as IDENT, 
     ChildID, 
     ParentID 
from C 
order by IDENT 
+0

Thx、そのトリックを – SWeko

+0

すごいトリック:) – SMK

+0

私のケースでは、私の場合、Occurences数は小さいです(10上)が、数が数百にある場合、これは再帰の制限を超えます。 – SWeko

4
;WITH CTEs 
AS 
(
    SELECT 1 [Id] 
    UNION ALL 
    SELECT [Id] + 1 FROM CTEs WHERE [Id] < 100 
) 
SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM CTEs ct 
JOIN @Children c1 ON c1.Occurences >= ct.[Id] 

シーケンスを生成する別の方法を、例えば、事前に定義されたテーブルを使用していますmaster.dbo.spt_values

SELECT ROW_NUMBER() OVER(ORDER BY c1.ChildID, c1.ParentID) [rn] 
    , c1.ChildID, c1.ParentID 
FROM master.dbo.spt_values ct 
JOIN @Children c1 ON c1.Occurences > ct.number 
    AND ct.type = 'P' 
+0

これは、基本的にソース表と数字表をジョインして、素敵な結合条件で結合します。 – SWeko

+0

私の場合、Occurences数は小さい(10本)ですが、数が数百になるとこれは再帰制限を超えます。数値表があらかじめ生成されていれば、それは回避できます。 – SWeko

+0

または "オプション(MAXRECURSION 0)"で終わる –

関連する問題