我有一张我自己做的桌子。我的样品表是这样的

-- Table genealogy
+--------+---------+------+-----+---------+-------+
| Field  | Type    | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| parent | int(11) | NO   | PRI | NULL    |       |
| child  | int(11) | NO   | PRI | NULL    |       |
+--------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

这个概念是这样的(为这个做好准备):
要查找user parent=1的子级,我查看user parent=1的第一级。
要查找user parent=1的孙子,我将查找user parent=1的子代的子代。
为了得到曾孙(第三级),我寻找的是一个孩子,他是父母的孩子的孩子=1。
……等等
可能会有点混乱,但我的查询工作得很好。我想知道是否有一种更快/优化的方法来实现这一点,因为我只是到处重复我的sql。
-- Get Child
SELECT parent, child AS '1st Level' FROM genealogy WHERE parent=1;

-- Get Grandchild
SELECT a.parent, b.child AS '2nd Level' FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent;

-- Get Great-Grandchild
SELECT a.parent, b.child AS '3rd Level' FROM (SELECT a.parent, b.child FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent) a INNER JOIN genealogy b ON a.child=b.parent;

-- And the list goes on

最佳答案

您可以使用另一个树结构(称为嵌套集):

-- Table genealogy
+--------+---------+------+-----+---------+-------+
| Field  | Type    | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| id     | int(11) | NO   | PRI | NULL    |       |
| lft    | int(11) | NO   | NO  | NULL    |       |
| rgt    | int(11) | NO   | NO  | NULL    |       |
+--------+---------+------+-----+---------+-------+

这将使您能够选择树中节点的所有子节点(以及子节点和子节点等等)。
例如,要选择系谱id为1的所有子项:
SELECT g2.*
FROM genealogy AS g1, genealogy AS g2
WHERE
  (g1.lft BETWEEN g2.lft AND g2.rgt)
AND
  (g1.id = 1);

更多信息和更多示例,请参见:http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html

关于mysql - 优化自我联接表,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8298131/

10-16 20:42