MySQL:使用表

时间:2015-12-07 12:43:15

标签: mysql sql database parent-child

我有类似这样的mysql表:

id | name| parent_id
---+-----+-----------
 1 | aaa | 0
 2 | bbb | 1
 3 | ccc | 2
 4 | ddd | 3
 5 | eee | 3
 6 | fff | 1
 7 | ggg | 0
 8 | hhh | 7
 9 | iii | 7

我需要创建一个查询来获取给定id的所有层次结构。

例如: 输入= 1,结果应该是这样的:

id | name| parent_id
---+-----+-----------
 1 | aaa | 0
 2 | bbb | 1
 3 | ccc | 2
 4 | ddd | 3
 5 | eee | 3
 6 | fff | 1

例如: 输入= 7,结果应该是这样的:

id | name| parent_id
---+-----+-----------
 7 | ggg | 0
 8 | hhh | 7
 9 | iii | 7

我尝试过这样的事情,但不知道如何继续。我不知道层次结构中有多少级别。

SELECT t1.id, t1.name, t1.parent_id, t2.name AS parent_name
FROM parent_test t1
LEFT JOIN parent_test t2 ON t1.parent_id=t2.id
WHERE t1.id=1 OR t1.parent_id=1;

任何想法?

1 个答案:

答案 0 :(得分:2)

只有父列,需要递归执行查询。这是MySQL无法做到的。

幸运的是,这是一个常见的问题,有一个共同的(虽然有些复杂)解决方案:documentation

  

嵌套集模型是一种在关系数据库中表示嵌套集(也称为树或层次结构)的特殊技术。

使用嵌套设置,您可以指定leftright列。 leftright之间的所有记录都是后代。

id | name| lft | rght
---+-----+-------------
 1 | aaa |   0 |   11
 2 | bbb |   1 |    8
 3 | ccc |   2 |    7
 4 | ddd |   3 |    4
 5 | eee |   5 |    6
 6 | fff |   9 |   10
 7 | ggg |  12 |   17
 8 | hhh |  13 |   14
 9 | iii |  15 |   16

现在,您可以执行简单查询以获取记录1的所有后代:

SELECT t1.* FROM parent_test t1
INNER JOIN parent_test t2 ON t1.lft >= t2.lft AND t1.rght <= t2.rght 
WHERE t2.id = 1

请注意,虽然读取查询很简单,但写入查询会增加复杂性。

插入时,您需要找到正确的left。权利始终为left + 1.接下来,您需要将right列增加2,以便列出right列更高的记录,因为插入了2个数字。

示例,要插入2的孩子。

START TRANSACTION;
SELECT `lft` + 1, `lft` + 2 FROM parent_test WHERE id = 2 INTO @lft, @rght
INSERT INTO parent_test (`name`, `lft`, `rght`) VALUES ('qqq', @lft, @rght);
UPDATE parent_test SET `rght` = `rght` + 2 WHERE `rght` > @rght;
COMMIT;

删除时,请执行相反的逻辑。要进行更新,请同时执行这两项操作。