2014-03-02 19 views
1

如果我有以下架构&数据和正在使用的封闭表模式:使用闭包表时,我将使用什么查询来获取兄弟记录?

+----+----------+------------+--------+ | id | ancestor | descendant | length | +----+----------+------------+--------+ | 1 | 2 | 2 | 0 | | 2 | 2 | 12 | 1 | | 3 | 2 | 13 | 1 | | 4 | 2 | 14 | 1 | | 5 | 2 | 15 | 1 | | 10 | 12 | 12 | 0 | | 11 | 13 | 13 | 0 | | 12 | 14 | 14 | 0 | | 13 | 15 | 15 | 0 | | 9 | 17 | 20 | 1 | | 8 | 17 | 19 | 1 | | 7 | 17 | 18 | 1 | | 6 | 17 | 17 | 0 | | 14 | 18 | 18 | 0 | | 15 | 19 | 19 | 0 | | 16 | 20 | 20 | 0 | +----+----------+------------+--------+

什么将我加入查询回到我的主表模样,以获得行ID 2的所有兄弟行?

+----+----------+------------+--------+ | id | ancestor | descendant | length | +----+----------+------------+--------+ | 3 | 2 | 13 | 1 | | 4 | 2 | 14 | 1 | | 5 | 2 | 15 | 1 | +----+----------+------------+--------+

回答

2

给定节点的兄弟姐妹也有同样的祖先。然而,这将包括“1”,以及你的列表:

select t.* 
from table t 
where t.ancestor = (select ancestor from table t2 where t.id = 2); 

在你的餐桌,我不知道这是什么意思为ancestor是一样descendant。但是,我认为以下是您要查询:

select t.* 
from table t 
where t.ancestor = (select ancestor from table t2 where t2.id = 2) and 
     t.ancestor <> t.descendant and 
     t.id <> 2; 

编辑:

你可以做到这一点作为一个明确加入这样的:

select t.* 
from table t join 
    table t2 
    on t.ancestor = t2.ancestor and 
     t2.id = 2 a 
where t.id <> 2 and 
     t.ancestor <> t.descendant; 

注:我还添加了条件t.id <> 2所以“2”不被认为是它自己的兄弟姐妹。

+0

我应该澄清一点,但有没有办法使用连接来做到这一点?我正在使用ORM并希望将所有连接建模为关系。 –

+0

我意识到的一个问题是,我不知道祖先是“2”。我需要从我的主数据表连接到这个获得所有兄弟姐妹,只知道这个闭包表的一行。 –

+0

@Omega。 。 。 “2”不是祖先。这是你想要兄弟姐妹的行的id。 –