我有类似这样的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;
任何想法?
答案 0 :(得分:2)
只有父列,需要递归执行查询。这是MySQL无法做到的。
幸运的是,这是一个常见的问题,有一个共同的(虽然有些复杂)解决方案:documentation。
嵌套集模型是一种在关系数据库中表示嵌套集(也称为树或层次结构)的特殊技术。
使用嵌套设置,您可以指定left
和right
列。 left
和right
之间的所有记录都是后代。
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;
删除时,请执行相反的逻辑。要进行更新,请同时执行这两项操作。