SQL Server 中的树结构数据查询

Posted

技术标签:

【中文标题】SQL Server 中的树结构数据查询【英文标题】:Tree structure data query in SQL Server 【发布时间】:2012-04-29 04:16:44 【问题描述】:

我有一个表 Person 有 3 列:Id, Name, ParentId 其中ParentId 是父行的Id

目前,要显示整个树,它必须遍历所有子元素,直到没有更多子元素。好像效率不高。

有没有更好更高效的方法来查询这些数据?

另外,有没有更好的方法在 SQL Server 数据库中表示这种树状结构?我的表/数据库的替代设计?

【问题讨论】:

请参阅***.com/questions/935098/… 以获取类似问题的答案。 查看 Bill Karwin 的 SQL Antipatterns strike back 幻灯片 - 他描述了几种反模式 - 其中包括您拥有的“幼稚树” - 并提供了可能的解决方案。他还有一本同名的好书SQL Antipatterns - 强烈推荐! 【参考方案1】:

假设您的父子关系水平有限,我认为设计没有任何问题。下面是一个使用递归 CTE 检索关系的快速示例:

USE tempdb;
GO

CREATE TABLE dbo.tree
(
    ID INT PRIMARY KEY,
    name VARCHAR(32),
    ParentID INT FOREIGN KEY REFERENCES dbo.tree(ID)
);

INSERT dbo.tree SELECT 1, 'grandpa', NULL
UNION ALL SELECT 2, 'dad', 1
UNION ALL SELECT 3, 'me', 2
UNION ALL SELECT 4, 'mom', 1
UNION ALL SELECT 5, 'grandma', NULL;

;WITH x AS
(
    -- anchor:
    SELECT ID, name, ParentID, [level] = 0
    FROM dbo.tree WHERE ParentID IS NULL
    UNION ALL
    -- recursive:
    SELECT t.ID, t.name, t.ParentID, [level] = x.[level] + 1
    FROM x INNER JOIN dbo.tree AS t
    ON t.ParentID = x.ID
)
SELECT ID, name, ParentID, [level] FROM x
ORDER BY [level]
OPTION (MAXRECURSION 32);
GO

别忘了清理:

DROP TABLE dbo.tree;

This might be a useful article. 一个替代方案是hierarchyid,但我发现它在大多数情况下过于复杂。

【讨论】:

与主题无关,但根据树的结构,您的“妈妈”和“爸爸”不是兄弟姐妹吗? :) 我的意思是日常生活的意思,就像他们有同一个父亲一样。哦,没关系 @Varvara 是的,当然。 @VarvaraKalinina 你应该得到比你拥有的更多的赞成票【参考方案2】:

Aaron Bertrands 的回答非常适合一般情况。如果您只需要一次显示整个树,您可以只查询整个表并在内存中执行树构建。这可能更方便和灵活。性能也会稍微好一些(无论如何都需要下载整个表,并且 C# 进行此类计算比 SQL Server 更快)。

如果您只需要树的一部分,则不建议使用此方法,因为您下载的数据会超出需要。

【讨论】:

以上是关于SQL Server 中的树结构数据查询的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 2008中的9种数据挖掘算法

如何使用 PHP 处理从 SQL 查询返回的树结构?

pl/sql如何现实像sqlserver中的树形结构目录界面,就是能查看表视图那样的界面。

C#中的树数据结构

如何获取 SQL Server 中的表结构?

HSQLDB中的树结构数据