Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server中具有多个父级的层次结构_Sql Server_Tree - Fatal编程技术网

Sql server SQL Server中具有多个父级的层次结构

Sql server SQL Server中具有多个父级的层次结构,sql-server,tree,Sql Server,Tree,我正在研究如何实现一个查询,该查询返回层次结构中所有节点的所有祖先(在所有级别,因此它包括直接祖先、祖先的祖先等等),该层次结构允许特定节点具有多个父节点 鉴于下表结构: Table Nodes: Id, Name Table Relations: IdNode, IdParentNode 一个类似的问题是,但我没有成功地将其适应我的情况。您可以使用递归CTE: DECLARE @IdNode INT -- use the correct data type SET @IdNode = 1

我正在研究如何实现一个查询,该查询返回层次结构中所有节点的所有祖先(在所有级别,因此它包括直接祖先、祖先的祖先等等),该层次结构允许特定节点具有多个父节点

鉴于下表结构:

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

一个类似的问题是,但我没有成功地将其适应我的情况。

您可以使用递归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)

选项(MAXRECURSION 200)
意味着它看起来只有200层深,如果要为所有层设置该选项(MAXRECURSION 0),可以使用
选项(MAXRECURSION 0)
(尽管确保在执行该操作之前查询可以完成)。

您可以使用递归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)

选项(MAXRECURSION 200)
意味着它看起来只有200层深,如果您想为所有层设置它,可以使用
选项(MAXRECURSION 0)
(尽管确保在执行之前查询可以完成)。

因为您想查询层次结构,您可以使用
hierarchyid
,并从中受益匪浅。 这将允许您查询特定级别,并进行高级查询,这些查询将根据节点级别和更多内容过滤和聚合数据。它还允许您返回特定节点的所有子节点,这就是您要执行的操作

但是,这也意味着使用不同于您所列出的表结构。
如果您对
hierarchyid
感兴趣,可以查看。

因为您想查询层次结构,所以可以使用
hierarchyid
,并从中受益匪浅。 这将允许您查询特定级别,并进行高级查询,这些查询将根据节点级别和更多内容过滤和聚合数据。它还允许您返回特定节点的所有子节点,这就是您要执行的操作

但是,这也意味着使用不同于您所列出的表结构。
如果您对
hierarchyid
感兴趣,可以查看。

据我所知,hierarchyid不能用于具有多个父级的层次结构…@user3104183这是正确的,它将无法正常工作。但是,您可以通过将系统视为许多树来添加对它的支持,然后通过在更新和插入过程中连接这些树(当它们重叠时),以及创建表示其他树的父树的连接表来链接这些树。它更麻烦,但仍然工作得很好。据我所知,HierarchyID不能用于具有多个父级的层次结构…@user3104183这是正确的,它无法在开箱即用的情况下正常工作。但是,您可以通过将系统视为许多树来添加对它的支持,然后通过在更新和插入过程中连接这些树(当它们重叠时),以及创建表示其他树的父树的连接表来链接这些树。它更麻烦,但仍然可以正常工作。@user3104183那么你为什么要求“层次结构中的特定节点”@user3104183无论如何,你可以从我的回答中删除
其中IdNode=@IdNode
,但我必须建议你不要创建该视图,它会非常慢,并且有可能挂起你的服务器这只会是第一级祖先。我明白了,但当我尝试删除重复项时(A的父母是B,C,B是C的孩子),当我使用UNION修改UNION ALL时,我收到了此错误消息:
递归公共表表达式“CTE”不包含顶级UNION ALL运算符
@user3104183。好吧,您需要测试它才能看到,我只需要确保警告您潜在的问题。但是,如果树上有那么多的行和级别,这应该不是什么大问题。您还需要确保您没有在
关系
表中添加在节点和父节点之间进行循环引用的行(并且永远不要添加具有自身作为父节点的节点的行)@user3104183那么您为什么要求“层次结构中的特定节点”?@user3104183,您可以从我的答案中删除
WHERE IdNode=@IdNode
,但我必须建议您不要创建该视图,它会非常慢,并且有可能挂起您的服务器这只会是第一级祖先。我明白了,但当我尝试删除重复项时(A有B,C作为父项,B是C的子项),当我使用UNION修改UNION ALL时,我收到了此错误消息:
递归公共表表达式“CTE”不包含顶级UNION ALL运算符
@user3104183。好吧,您需要测试它才能看到,我只需要确保警告您潜在的问题。但是,如果树上有那么多的行和级别,这应该不是什么大问题。您还需要确保不要在
关系
表中添加在节点和父节点之间进行循环引用的行(也不要添加具有自身作为父节点的节点的行)。此问题需要指定有关解决方案要求的其他详细信息。就目前情况而言,您已在每个回答中指定了回答问题的其他细节,这些细节最初并未包含在问题中。为了避免混淆,请在此处添加这些详细信息,并更具体一点。此问题需要指定有关解决方案要求的其他详细信息。就目前情况而言,您已在每个回答中指定了回答问题的其他细节,这些细节最初并未包含在问题中。为了避免混淆,请在此处添加这些详细信息,并更具体一点。