从自引用表中获取层次结构数据

Posted

技术标签:

【中文标题】从自引用表中获取层次结构数据【英文标题】:Getting hierarchy data from self-referencing tables 【发布时间】:2011-01-13 02:01:52 【问题描述】:

假设您有下表:

items(item_id, item_parent)  

...它是一个自引用表 - item_parent 引用 item_id

您将使用什么 SQL 查询来选择表中的所有项目及其深度,其中项目的深度是该项目的所有父项和祖父项的总和。

如果以下是表格的内容:

item_id     item_parent
----------- -----------
1           0          
2           0            
3           2          
4           2          
5           3          

...查询应检索以下对象集:

"item_id":1,"depth":0 "item_id":2,"depth":0 "item_id":3,"depth":1 "item_id":4,"depth":1 "item_id":5,"depth":2

附:我正在寻找支持 mysql 的方法。

【问题讨论】:

什么数据库和版本?如果完全支持,递归查询是特定于供应商的。 @RBarryYoung:假设他使用的是 MS SQL Server。 没错,但递归 CTE 标准的一部分,而 SQL Server 不是唯一支持它们的产品。 Emmanuil:如果您需要 MySql 特定的答案,那么您应该在某处指定。 @RBarryYoung:对此我深表歉意。我错误地认为答案适用于任何 DBMS。 【参考方案1】:

如果数据库是 SQL 2005 / 2008 那么...

最简单的方法是使用设计为递归的 CTE(公用表表达式)。

 WITH myCTE (Item_id, Depth)
 AS
 (
    Select Item_ID, 0 as Depth From yourTable where Item_Parent=0
    Union ALL
    Select yourTable.Item_ID, Depth + 1 
    From yourTable 
    inner join myCte on yourTable.item_Parent = myCte.Item_Id
 )

 Select Item_id, Depth from myCTE

输出如下:

Item_Id  Depth
    1   0
    2   0
    3   1
    4   1
    5   2

您可以根据需要对其进行格式化。

【讨论】:

感谢您的建议!我很想看到 MySQL 支持的方法。 Emanuil:您有责任在人们尝试回答您的问题之前通知他们实施要求(如 MySQL)【参考方案2】:

mysql网站上有一篇关于MySql中分层数据的技术文章不错: Managing Hierarchical Data in MySQL - 你可以在那里找到一些详细的解决方案,有优缺​​点。

尤其是关于“嵌套集模型”和“寻找节点的深度”的部分你应该会感兴趣。

【讨论】:

如果有人想知道 Doctrine 是否支持这一点,有一个很好的扩展:github.com/Atlantic18/DoctrineExtensions/blob/master/doc/…【参考方案3】:

Oracle 有一种非常方便的语法来检索分层数据,如下所示:

select
    item_id,
    item_parent,
    level as depth
from
    items
connect by
    prior item_id = item_parent
start with
    item_parent not in (select item_id from items)

这从树的根节点作为 item_parent 在表中不存在的项目作为 item_id 开始,并选择这些节点的所有子节点,以及它们在树中的深度。

【讨论】:

我不知道甲骨文有这个。这很高兴知道。如果父母在 item_parent 列中有一个空值,这样我们可以避免“不在”和额外的选择,那不是更有效吗【参考方案4】:

MySQL

http://www.artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

编辑:删除不必要的信息

【讨论】:

很遗憾,artfulsoftware.com/mysqlbook/sampler/mysqled1ch20.html 链接已失效。【参考方案5】:

我需要为同一个任务找到解决方案,找到了一些文章,但仍然没有选择走哪条路……

http://explainextended.com/2009/07/20/hierarchical-data-in-mysql-parents-and-children-in-one-query/

这些链接可能会对您有所帮助。如果您找到一个好的解决方案 - 请在此处发布。我不能发布超过 1 个链接 - 我会在下一篇文章中添加一些

【讨论】:

evolt.org/article/Four_ways_to_work_with_hierarchical_data/17/… alandelevie.com/2008/07/12/…

以上是关于从自引用表中获取层次结构数据的主要内容,如果未能解决你的问题,请参考以下文章

使用 EntityFramework.Core 从自引用表加载完整的层次结构

从自连接表中获取最短持续时间

如何从自定义表格视图单元类中获取对表格视图控制器的引用

MDX 获取层次结构值

Laravel,如何从自定义表的 jwt 令牌获取登录用户

获取 BIRT 报告数据的正确方法