MySql的递归查询 - 获取所有子树

时间:2014-11-09 14:07:32

标签: mysql recursion view recursive-query

让我们假设有一家工厂生产产品。工厂有产品目录,因此tbl_catalog将是。

+----------------+--------------+-----------------------------------------------+
| catalog_number | catalog_name | details                                       |
+----------------+--------------+-----------------------------------------------+
|              1 | LaptopX      | Full assembled laptop - X                     |
|              2 | Top Half     | Where the screen & webcam are                 |
|              3 | Bottom Half  | Where mothereboard, and rest of the parts are |
|              4 | WebCam       | WebCam for laptopX                            |
|              5 | LcdX         | Lcd screen for laptopX                        |
|              6 | Keyboard     | set of keys                                   |
|              7 | SSD          | Place to store data                           |
|              8 | Touchpad     | If there is no mouse connected                |
|              9 | DVD          | to play music and watch movies                |
|             10 | Lazer Beam   | a must have for our DVD                       |
|             11 | EngineX      | EngineX will spin our DVD with no problem     |
+----------------+--------------+-----------------------------------------------+

目录中其他产品组成的产品 - 以树形式表示,我们的样本tbl_catalog_tree将是:

+-----------+----------+
| parent_id | child_id |
+-----------+----------+
|         1 |        2 |
|         1 |        3 |
|         2 |        4 |
|         2 |        5 |
|         3 |        6 |
|         3 |        7 |
|         3 |        8 |
|         3 |        9 |
|         9 |       10 |
|         9 |       11 |
+-----------+----------+

目录的那个。现在让我们组装一些产品。我们需要另一张表 - assembly

+------+----------------+--------------+-------+
| id   | catalog_number | assembled_by | qc_by |
+------+----------------+--------------+-------+
|  100 |             11 | Joe          | Dan   |
|  101 |             11 | Joe          | Dan   |
|  102 |             11 | Joe          | Dan   |
|  200 |             10 | Joe          | Dan   |
|  201 |             10 | Joe          | Dan   |
|  201 |             10 | Joe          | Dan   |
|  300 |              9 | Mike         | Dan   |
|  301 |              9 | Mike         | Dan   |
|  302 |              9 | Mike         | Dan   |
+------+----------------+--------------+-------+

但我们仍然不知道DVD子部件之间的连接是什么,所以我们需要tbl_assembly_tree

+-----------+----------------------+----------+
| parent_id | child_catalog_number | child_id |
+-----------+----------------------+----------+
|       302 |                   11 | 100      |
|       302 |                   10 | 200      |
|       301 |                   11 | 101      |
|       301 |                   10 | 201      |
|       300 |                   11 | 102      |
|       300 |                   10 | 202      |
+-----------+----------------------+----------+

由于子树可以是不同目录的一部分(比如这张可以作为laptopX和未来笔记本电脑的一部分的DVD),我们需要知道特定程序集的子目录号是什么(并且不依赖于目录树结构) )。

我的问题是: 如何查询,以便获得产品及其所有子树产品? 如果我想查询数据库中有关目录号的所有已组合项目的信息,并且每个程序集都要知道谁构建,并且递归地查询了所有它的子部分,在上面的示例中,如果我查询DVD,我想要回答是这样的:

+----+---------+----------+---------+--------+------------+----------+--------+-------+
| id | cat_num | cat_name | assy_by | sub_id |sub_cat_num | sub_name | ass_by | qc_by |
+----+---------+----------+---------+--------+------------+----------+--------+-------+
| 300|     9   |   DVD    |  Mike   |   102  |  11        | EngineX  |  Joe   | Dan   |
| 300|     9   |   DVD    |  Mike   |   202  |  10        | Lazer B  |  Joe   | Dan   |
| 301|     9   |   DVD    |  Mike   |   101  |  11        | EngineX  |  Joe   | Dan   |
| 301|     9   |   DVD    |  Mike   |   201  |  10        | Lazer B  |  Joe   | Dan   |
| 302|     9   |   DVD    |  Mike   |   100  |  11        | EngineX  |  Joe   | Dan   |
| 302|     9   |   DVD    |  Mike   |   200  |  10        | Lazer B  |  Joe   | Dan   |
+----+---------+----------+---------+--------+------------+----------+--------+-------+

当然,如果所有目录只有一个级别我不会在这里提出这个问题,但是我需要这个是递归的,所以我可以看到我选择的目录号的所有汇编子树。< / p>

我已经建立了sqlfiddle for the above example并希望有人可以帮助我

1 个答案:

答案 0 :(得分:0)

考虑到的诀窍是多次加入同一个表。

这将为您提供您在问题中说明的结果:

SELECT
    d.parent_id as id,
    a.catalog_number,
    a.catalog_name,
    e.assembled_by,
    d.child_id as sub_id,
    b.child_id as sub_cat_num,
    c.catalog_name as sub_name,
    f.assembled_by as sub_assemly_by,
    e.qc_by

FROM
    catalog as a, catalog_tree as b, 
    catalog as c, assembly_tree as d, 
    assembly as e , assembly as f

WHERE 
    a.catalog_name = 'DVD'
    and a.catalog_number = b.parent_id
    and b.child_id = c.catalog_number
    and b.child_id = d.child_catalog_number
    and d.parent_id = e.id
    and d.child_id = f.id
ORDER BY 1