使用MySQL查询遍历行以生成递归树

php*_*meh 20 mysql recursion

我有一个物料清单表,设置如下:
item - parent

显示物料清单时的最终结果是它显示如下:

item 1  - parent 0    
    item 2 - parent 1    
    item 3 - parent 1    
Run Code Online (Sandbox Code Playgroud)

最终结果也可能是多层次的,如下所示:

item 3 - parent 0    
    item 4 - parent 3    
    item 76 - parent 3    
Run Code Online (Sandbox Code Playgroud)

它可以无限制地继续下去:

item 76 - parent 0    
    item 46 - parent 76    

item 46 - parent 0     
    item 25 - parent 46
Run Code Online (Sandbox Code Playgroud)

现在,我要么从数据库中获得1个级别:

SELECT * FROM bom WHERE parentId = $itemId (shorthand)

或者从表中拉出每一行并使用我的递归函数来理清我需要的那些,但这显然是低效的,因为我可能只需要10行,但我拉了10,000条记录.递归函数的输出只会创建一个这样的树:

item 1
   item 2
   item 3
      item 4
      item 76
         item 46
            item 25
Run Code Online (Sandbox Code Playgroud)

我所知道的是,我从第1项开始.第5项的父母可以是11; 他们不必顺序.我希望得到树中的所有子分支.我怎么能在mysql中执行此查询?

Rol*_*DBA 36

早在2011年10月24日,有人在DBA StackExchange中发布了一个关于MySQL中树遍历的问题.SQL for MySQL不支持它.

我在回答这个问题时写了三(3)个存储过程(GetParentIDByID,GetAncestry和GetFamilyTree).希望这些信息可以帮助您构建您想要的东西.


Mar*_*ers 16

Bill Karwin发布了一个关于MySQL中的层次数据的幻灯片.如果可以选择更改数据库设计,则可以使用其他一些有吸引力的方法来存储数据,以便于查询.他介绍的方法是:

  • 邻接清单
  • 路径枚举
  • 嵌套集
  • 关闭表

幻灯片69有一个很好的表格,显示了每种方法的优缺点,因此我建议您首先查看该幻灯片,看看哪种方法可能适用于您,然后返回查看如何实现它的详细信息.请注意,您选择的设计(邻接列表)是所呈现的四种设计中唯一一种难以查询子树的设计.

话虽如此,如果你不能改变你的设计或者你想坚持邻接列表,那么我必须同意Didier的观点,你应该看看Quassnoi的文章"MySQL中的分层查询".这是一篇非常明确的文章,并解释了如何有效地编写查询.

  • 很棒的资源.我把它作为赏金来获取信息.谢谢! (2认同)

Did*_*zia 7

AFAIK,用MySQL做这件事并非易事.

这是一套很好的文章:

http://explainextended.com/2009/03/17/hierarchical-queries-in-mysql/


Ulu*_*aiv 6

MySQL (8) 现在支持递归查询。

考虑到您的表项(id,父级)和 id = 1 的起始项,以下内容可以完成这项工作:

with recursive result(id, parent) as 
   (select id, parent 
    from item where id = 1 
    union all 
    select i.id, i.parent 
    from item i 
    join result on i.parent = result.id) 

select * from result;
Run Code Online (Sandbox Code Playgroud)