20

我有一个这样设置的物料清单表:
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

4 回答 4

37

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

在我对该问题的回答中,我编写了三 (3) 个存储过程(GetParentIDByID、GetAncestry 和 GetFamilyTree)。希望这些信息可以帮助您构建您正在寻找的东西。

于 2012-06-14T15:03:11.237 回答
16

Bill Karwin发布了一个关于MySQL 中的层次结构数据的幻灯片。如果可以选择更改数据库设计,那么还有其他一些吸引人的方法来存储数据以使其更易于查询。他涵盖的方法是:

  • 邻接表
  • 路径枚举
  • 嵌套集
  • 封闭表

幻灯片 69 有一张很好的表格,显示了每种方法的优缺点,所以我建议你先看看这张幻灯片,看看哪种方法适合你,然后再回去看看如何实现它的细节。请注意,您选择的设计(邻接表)是所呈现的四种设计中唯一一种难以查询子树的设计。

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

于 2012-06-13T22:54:40.263 回答
7

AFAIK,用 MySQL 做到这一点并非易事。

这是一组关于它的好文章:

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

于 2012-05-18T08:06:12.873 回答
3

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;
于 2019-02-19T12:29:05.343 回答