2011-07-07 132 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

另外一件事情,在我的情況下,發生次數很少(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

在我的情況下,發生次數很少(10次),但如果次數在幾百次,則會超過遞歸限制。如果數字表是預生成的,那麼這可能會被迴避。 – SWeko

+0

或用「選項(MAXRECURSION 0)」進行迴避 –