2014-01-23 190 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这是正确的,它将无法正确使用。但是您可以通过将系统视为许多树来处理系统,然后在更新时将它们连接起来,并在重叠时插入树,并通过制作表示树作为其他树的父项的连接表来添加对它的支持。这更麻烦,但仍然运作良好。 –