2016-10-12 111 views
1
FromID    ToID  
-------------- ----------  
    1    2    
    2    3     
    3    4     
    5    6     
    6    7     
    9    10 

我想用在SQL Server 2008中遞歸查詢創建一個輸出作爲SQL Server 2008的遞歸查詢

FromID    Path 
1      1,2,3,4 
5      5,6,7           
9      9,10 

我一直在努力構建一個SQL語句中使用參照網上的例子如下

;WITH items AS (
    SELECT FromID 
    , CAST(FromID AS VARCHAR(255)) AS Path 
    FROM tablex 
    UNION ALL 
    SELECT i.FromID 
    , CAST(Path + '.' + CAST(i.FromID AS VARCHAR(255)) AS VARCHAR(255)) AS Path 
    FROM tablex i 
    INNER JOIN items itms ON itms.FromID = i.ToID 
) 
SELECT * 
FROM items 
ORDER BY Path 

但是,上述不起作用。有任何想法嗎?

+0

所以2-3將不獲得自己的行,但6-9會因爲你有6-7以前? –

+0

嗨,爲了簡化,我已經拿出6-9。它就像一棵樹結構,其中1,5,9是根ID。我需要每個根的孩子ID – user3050151

回答

1

爲什麼你的預期輸出是它是什麼它不是完全清楚給我。從6-10的路徑不是10的完整路徑:該路徑始於ID 5.我已經寫了輸出的完整路徑,說明你會如何去這樣做的例子。如果你確實希望它由於某種原因從6開始,那麼請清楚地說明確定哪些節點應該作爲結果集中的起點出現的規則。

我注意到,在您的樣本數據中的每個ID只能有一個前身,但潛在的多個接班人。出於這個原因,我選擇從識別端點節點開始,然後回溯到起點。希望下面的代碼註釋足以解釋正在發生的其他事情。

declare @TableX table (FromID int, ToID int); 
insert @TableX values (1, 2), (2, 3), (3, 4), (5, 6), (6, 7), (6, 9), (9, 10); 

with PathCTE as 
(
    -- BASE CASE 
    -- Any ID that appears as a "to" but not a "from" is the endpoint of a path. This 
    -- query captures the ID that leads directly to that endpoint, plus the path 
    -- represented by that one row in the table. 
    select 
     X1.FromID, 
     [Path] = convert(varchar(max), X1.FromID) + ',' + convert(varchar(max), X1.ToID) 
    from 
     @TableX X1 
    where 
     not exists (select 1 from @TableX X2 where X2.FromID = X1.ToID) 

    union all 

    -- RECURSIVE CASE 
    -- For every path previously identified, look for another record in @TableX that 
    -- leads to its starting point and prepend that record's from ID to the overall path. 
    select 
     X.FromID, 
     [Path] = convert(varchar(max), X.FromID) + ',' + PathCTE.[Path] 
    from 
     PathCTE 
     inner join @TableX X on PathCTE.FromID = X.ToID 
) 

-- Any ID that appears as a "from" but not a "to" is the starting point of one or more 
-- paths, so we get all results beginning at one of those points. All other output from 
-- PathCTE is partial paths, which we can ignore. 
select * 
from 
    PathCTE 
where 
    not exists (select 1 from @TableX X where PathCTE.FromID = X.ToID) 
order by 
    FromID, [Path]; 

輸出:

FromID Path 
1  1,2,3,4 
5  5,6,7 
5  5,6,9,10 
+0

嗨,謝謝。我試圖簡化我的問題。我其實有兩張桌子。第二個表包含每個節點的座標。例如記錄1-coords1,2-coords2,3-coords3,4-coords4等。我還需要加入2個表格,以便最終得到一個輸出,其中字段'Path'返回座標 – user3050151

+0

@ user3050151:這聽起來應該只是對上面查詢中CTE內部的兩個'select'語句的簡單修改。修改每個'from'子句以從'@ TableX'連接到第二個表,然後修改'[Path]'的定義以使用第二個表中相應的字段替代'X.FromID'。 –