优化自联接表

时间:2011-11-28 15:28:59

标签: mysql join

我有一张桌子,我自己加入。我的示例表看起来像这样

-- 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)

这个概念是这样的(为此做好准备):

  1. 要查找用户parent = 1的子项,我会查看用户parent = 1的第一级。
  2. 要查找用户parent = 1的孙子,我会查找用户父级= 1的孩子的孩子。
  3. 为了得到曾孙(第3级),我寻找孩子是父母子女的孩子= 1。
  4. ......等等
  5. 它可能会有点混乱,但我的查询工作得很好。我想知道是否有更快/更优化的方式,因为我只是在整个地方重复我的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
    

1 个答案:

答案 0 :(得分:1)

您可以使用其他树结构(称为嵌套集):

-- 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