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

时间:2012-05-18 04:46:51

标签: mysql recursion

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

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

item 1  - parent 0    
    item 2 - parent 1    
    item 3 - parent 1    

最终结果也可能是多层次的:

item 3 - parent 0    
    item 4 - parent 3    
    item 76 - parent 3    

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

item 76 - parent 0    
    item 46 - parent 76    

item 46 - parent 0     
    item 25 - parent 46

现在,我要么从数据库中获得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

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

4 个答案:

答案 0 :(得分:36)

早在2011年10月24日,有人发布了question in the DBA StackExchange about tree traversal in MySQL。 SQL for MySQL不支持它。

我在my answer to that question中写了三(3)个存储过程( GetParentIDByID,GetAncestry和GetFamilyTree )。希望这些信息可以帮助您构建您想要的东西。

答案 1 :(得分:16)

Bill Karwin在MySQL发布了关于heirarchical data的幻灯片。如果可以选择更改数据库设计,则可以使用其他一些有吸引力的方法来存储数据,以便于查询。他所涉及的方法是:

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

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

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

答案 2 :(得分:7)

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

这是一篇很好的文章:

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

答案 3 :(得分:1)

如今的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;