2014-01-23 191 views
1

我在查看如何實現一個查詢,該查詢返回層次結構中所有節點的所有祖先(在所有級別,因此它包括直接祖先,祖先的祖先等等)允許多個父母爲特定的節點。在SQL Server中具有多個父項的層次結構

如下表結構:

Table Nodes: Id, Name 
Table Relations: IdNode, IdParentNode 

類似的問題是SQL Server - Get all children of a row in many-to-many relationship?,但我沒有成功,以使其適應我的情況。

+1

此問題需要指定有關解決方案要求的其他詳細信息。就目前而言,您在每個答案中都指定了其他細節,以回答答案,答案中最初並未包含在問題中。爲了避免混淆,請在此處添加這些詳細信息並更具體一些。 –

回答

5

您可以使用遞歸CTE:

DECLARE @IdNode INT -- use the correct data type 
SET @IdNode = 1 -- here use the node you want to search 

;WITH CTE AS 
(
    SELECT IdNode, 
      IdParentNode Ancestor, 
      1 TreeLevel 
    FROM Relations 
    WHERE IdNode = @IdNode 
    UNION ALL 
    SELECT A.IdNode, 
      B.IdParentNode, 
      TreeLevel + 1 
    FROM CTE A 
    INNER JOIN Relations B 
     ON A.Ancestor = B.IdNode 
) 
SELECT * 
FROM CTE 
OPTION(MAXRECURSION 200) 

OPTION(MAXRECURSION 200)意味着它看起來只有200級深,你可以使用OPTION(MAXRECURSION 0)如果你想設置爲所有級別(雖然確保查詢可以在做之前完成)。

+0

@ user3104183那麼爲什麼你問「在層次結構中的特定節點」? – Lamak

+0

@ user3104183無論如何,你*可以從我的答案中刪除'WHERE IdNode = @ IdNode',但我不得不建議你不要創建這個視圖,它會非常慢,並且有可能會掛起你的服務器 – Lamak

+0

這隻會成爲祖先的第一級。 –

0

由於您要查詢層次結構,因此您可以使用hierarchyid並從中受益匪淺。 這將允許您查詢特定級別並進行高級查詢,這些查詢將根據節點級別和更多內容過濾和聚合數據。它也可以讓你返回特定節點的所有孩子,這就是你想要做的。

但是,這也意味着使用不同於您列出的表結構。 如果您對hierarchyid感興趣,您可以查看this information

+0

正如我所理解的,HierarchyID不能用於具有多個父項的層次結構... – user3104183

+1

@ user3104183這是正確的,它將無法正確使用。但是您可以通過將系統視爲許多樹來處理系統,然後在更新時將它們連接起來,並在重疊時插入樹,並通過製作表示樹作爲其他樹的父項的連接表來添加對它的支持。這更麻煩,但仍然運作良好。 –