2014-04-07 64 views
1

我有以下表結構Sql Server的CTE親子遞歸

create table Test(
    ParentId int, 
    ChildId int 
) 

insert into Test(ParentId, ChildId) 
select 1, NULL 
union 
select 1, 2 
union 
select 1, 3 
union 
select 2, NULL 
union 
select 2, 5 
union 
select 5, 6 
union 
select 6, 5 
union 
select 6, 8 

我試圖建立一個結果集的所有父子直接和間接關係的。因此,假設我通過PARENTID = 2的參數,我想結果集爲下面正好返回:

ParentId ChildId 
------------------- 
2   NULL 
2   5 
5   6 
6   8 
1   2 

所以基本上這顯示了所有可能的聯繫可以在一個表中找到父ID = 2. 從Parent本身開始,它具有Child Id,然後與Child Id 6有其他關係。此外,Parent Id 2屬於父ID 1,它也應顯示在結果集中。請注意,這種關係可能會擴展到N個等級。我希望你明白我在這裏想達到的目標,如果沒有,請讓我知道,這樣我可以更清楚地解釋。

到目前爲止,我想出了下面的遞歸查詢,但它拋出一個如下所述的錯誤:

DECLARE @ID INT = 2 

;WITH MyCTE 
AS (
    SELECT ParentId 
     ,ChildId 
    FROM Test 
    WHERE ParentId = @ID 

    UNION ALL 

    SELECT T.ParentId 
     ,Test.ChildId 
    FROM Test 
    INNER JOIN MyCTE T ON Test.ParentID = T.ChildId 
    WHERE Test.ParentID IS NOT NULL 
    ) 
SELECT * 
FROM MyCTE 

Error: 
The statement terminated. The maximum recursion 100 has been exhausted before statement completion 

我都忍了代碼的SQLFiddle here爲你們來測試和嘗試。

我真的很感激任何人指導和幫助我實現我想要的結果。

+1

您的數據中有循環引用。 5是父對象6,6是父對象5.這使得遞歸循環和......這是你的數據實際上是什麼樣子? –

+0

除了循環引用 - 在結果的最後獲取(父,子)1,2的條件是什麼? –

+0

@MikaelEriksson是的,這就是數據的樣子,因爲在兩個人之間可以存在許多類型的關係。 –

回答

4

As #Mikael Eriksson說:「你的數據中有一個循環引用,5是父對象6,而6是父對象5。

同樣在遞歸部分中,您從上一步輸出ParentId,而不是從剛纔找到的行輸出。

declare @Test table (ParentId int, ChildId int) 

insert into @Test (ParentId, ChildId) 
select 1, null 
union all 
select 1, 2 
union all 
select 1, 3 
union all 
select 2, null 
union all 
select 2, 5 
union all 
select 5, 6 
union all 
--select 6, 5 
--union all 
select 6, 8 

declare @id int = 2 

;with MyCTE as (
    select ParentId, ChildId 
    from @test 
    where ParentId = @id 

    union all 

    select t2.ParentId, t2.ChildId 
    from MyCTE t1 
    inner join @Test t2 on t1.ChildId = t2.ParentId 
) 

select * from MyCTE 

另一件事我不明白的是爲什麼你有這樣的行,其中ChildId爲null,並且ParentId不爲空。怎麼可能?

這是否意味着您有未知的父項已知的項目?

+0

ChildId爲空以指定該特定行是父級行。更像它是根節點。 –

+0

如果它是一個根節點,那麼parentid應該是null,並且childid應該被填充。一個根不能有父母,但它會有孩子。 –