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。好吧,您需要测试它才能看到,我只需要确保警告您潜在的问题。但是,如果树上有那么多的行和级别,这应该不是什么大问题。您还需要确保不要在关系
表中添加在节点和父节点之间进行循环引用的行(也不要添加具有自身作为父节点的节点的行)。此问题需要指定有关解决方案要求的其他详细信息。就目前情况而言,您已在每个回答中指定了回答问题的其他细节,这些细节最初并未包含在问题中。为了避免混淆,请在此处添加这些详细信息,并更具体一点。此问题需要指定有关解决方案要求的其他详细信息。就目前情况而言,您已在每个回答中指定了回答问题的其他细节,这些细节最初并未包含在问题中。为了避免混淆,请在此处添加这些详细信息,并更具体一点。