【问题标题】: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。

标签: mysql sql recursion hierarchy


【解决方案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 - 你可以在那里找到一些详细的解决方案,有优缺​​点。

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

【讨论】:

【解决方案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】:
【解决方案5】:

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

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

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

猜你喜欢
  • 1970-01-01
  • 2014-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多