2017-09-13 107 views
0

我有抓住一个树节点下面的SQL和它的父:加入父到子节点分层表结构

SELECT 
     c.id 
    , c.tag 
    , (
      SELECT 
        s.id 
      FROM treeTable s 
      WHERE s.lft < c.lft AND s.rgt > c.rgt 
      ORDER BY s.rgt - c.rgt ASC 
      LIMIT 1 
     ) AS parent 
FROM treeTable c; 

但问题是,我也想s.tag表里面,但我可以”从子查询中选择两列。我该如何去重构这个SQL以便能够选择两列?

我已经看了很多资源可能尝试一个左连接,但不能得到任何工作。我想不出一个简单的分组操作的或者由于需要在子查询中使用ORDER BY和LIMIT

编辑:表的结构如下所示:

Field  Type    Collation   Null Key  Default Extra   Privileges      Comment 
-------- ---------------- ----------------- ------ ------ ------- -------------- ------------------------------- --------- 
id  int(10)   (NULL)    NO  PRI  (NULL) auto_increment select,insert,update,references      
tag  varchar(255)  latin1_swedish_ci NO    (NULL)     select,insert,update,references   
lft  int(11)   (NULL)    NO  MUL  (NULL)     select,insert,update,references   
rgt  int(11)   (NULL)    NO  MUL  (NULL)     select,insert,update,references   

回答

0

试试这个,使用两个低效子选择

SELECT 
c.id, 
c.tag, 
(
    SELECT 
     s.id 
    FROM treeTable s 
    WHERE s.lft < c.lft AND s.rgt > c.rgt 
    ORDER BY s.rgt - c.rgt ASC 
    LIMIT 1 
) AS parent, 
(
    SELECT 
     s.tag 
    FROM treeTable s 
    WHERE s.lft < c.lft AND s.rgt > c.rgt 
    ORDER BY s.rgt - c.rgt ASC 
    LIMIT 1 
) AS parent_tag 
FROM treeTable c; 

看起来在逻辑上是正确的。不能测试它抱歉。在这种情况下,如果你确实经常使用它,你应该重新设计一个具有更好定义的父子链接的表格

+0

这个解决方案效率低下,我查询的表有数百万个条目,并且不断地越来越多。我不希望每个查询都有两个子查询。告诉我重新设计这个设计也不是一个有效的答案,因为这个表格表现出非常好的设计。 虽然我很感谢你的帮助,但是谢谢! –

+0

我完全理解。在你的情况下,困难源于这样一个事实,即你在一个范围内进行链接并使用一个技巧(极限1)来获得在大多数情况下应该是JOIN的最高结果。我最初编写了一个带有MIN距离的JOIN版本(s.rgt - c.rgt),但不能保证获得s.id和s.tag ....希望你找到一个解决方案。 –