2016-11-12 13 views
0

我想实现一个简单的菜单模型的闭包表模式,但我遇到了一些困难,建立查询找到所有兄弟姐妹当前节点而不具有子查询(例如,具有连接)。如何使用SQL闭包表格模式(无子查询!)获取所有兄弟姐妹

有一个old question非常类似于我的,但似乎没有答案(或者至少我不明白它)。

采取例如以下简化方案(不包括零个深度记录):

menu: 
+--+--------------+ 
| id | title  | 
+--+--------------+ 
| 1 | Link 1  | 
| 2 | Link 1.1 | 
| 3 | Link 1.2 | 
| 4 | Link 1.3 | 
| 5 | Link 1.3.1 | 
| 6 | Link 1.3.2 | 
+----+------------+ 

menu_closure: 
+----------+------------+-------+ 
| ancestor | descendant | depth | 
+----------+------------+-------+ 
| 1  | 2   | 1  | 
| 1  | 3   | 1  | 
| 1  | 4   | 1  | 
| 1  | 5   | 2  | 
| 1  | 6   | 2  | 
| 4  | 5   | 1  | 
| 4  | 6   | 1  | 
+----------+------------+-------+ 

欲获得链接1.1(ID = 2)的所有兄弟 - >链接1.2(ID = 3)和链接1.3(id = 4)。

注意:我只知道目标menu记录的编号。

目前,我做到以下几点:

SELECT m.* 
FROM menu AS m 
LEFT JOIN menu_closure AS mc ON mc.descendant=m.id 
WHERE m.id != 2 
    AND mc.depth = 1 
    AND mc.ancestor = (SELECT ancestor FROM menu_closure WHERE descendant=3 AND depth=1) 

,我想是先获取链接1.1的父母,然后通过排除链接1.1的ID获取其子女的另一种选择,但我只搜索一个查询的解决方案。

+0

我无法证实任何问题,请参阅http://sqlfiddle.com/#!9/f671c6/1/0 –

+0

如果我理解正确,你的查询是“给我所有与x相同的祖先和深度的项目。”不知何故,你不得不查找直接的祖先来链接1.1来完成这项工作。对当前查询进行调整:你可以使用一个内部的'JOIN'(不是LEFT)并且应该是'... descendant = 2 ...'如果你真的不想要子查询,你可以将menu_closure自己加入在你链接的例子中,但子查询对于下一个必须处理代码的人来说似乎更加透明。 – Jerry

+1

@OlafDietsche查询工作正常,但我正在寻找一个解决方案(没有子查询) – nevermind

回答

1

您的ancestor

select * 
from menu_closure a 
where a.descendant = 2 

首先检查,然后在同一深度拿起兄弟姐妹

select * 
from menu_closure a 
join menu_closure s on s.ancestor = a.ancestor 
where a.descendant = 2 

为 “通1.1”

select * 
from menu_closure a 
join menu_closure s on s.ancestor = a.ancestor 
where a.descendant = 2 
    and s.depth = a.depth 

添加菜单标题

select * 
from menu_closure a 
join menu_closure s on s.ancestor = a.ancestor 
join menu m on m.id = s.descendant 
where a.descendant = 2 
    and s.depth = a.depth 

,并排除一切不想要的

select m.* 
from menu_closure a 
join menu_closure s on s.ancestor = a.ancestor 
join menu m on m.id = s.descendant 
where a.descendant = 2 
    and s.depth = a.depth 
    and m.id <> 2 

最终sqlfiddle

+0

感谢您的详细解答。 – nevermind