如何使用SQL闭包表格模式(无子查询!)获取所有兄弟姐妹
问题描述:
我想实现一个简单的菜单模型的闭包表模式,但我遇到了一些困难,建立查询找到所有兄弟姐妹当前节点而不具有子查询(例如,具有连接)。如何使用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获取其子女的另一种选择,但我只搜索一个查询的解决方案。
答
您的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
+0
感谢您的详细解答。 – nevermind
我无法证实任何问题,请参阅http://sqlfiddle.com/#!9/f671c6/1/0 –
如果我理解正确,你的查询是“给我所有与x相同的祖先和深度的项目。”不知何故,你不得不查找直接的祖先来链接1.1来完成这项工作。对当前查询进行调整:你可以使用一个内部的'JOIN'(不是LEFT)并且应该是'... descendant = 2 ...'如果你真的不想要子查询,你可以将menu_closure自己加入在你链接的例子中,但子查询对于下一个必须处理代码的人来说似乎更加透明。 – Jerry
@OlafDietsche查询工作正常,但我正在寻找一个解决方案(没有子查询) – nevermind