我正在尝试为一个简单的菜单模型实现闭包表模式,但是在构建查询以查找当前节点的所有兄弟节点没有子查询时遇到了一些困难(例如,使用加入)。
有一个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 |
+----------+------------+-------+
我想要获取 Link 1.1 (id=2) -> Link 1.2 (id=3) 和 Link 1.3 (id=4) 的所有同级。
注意:我只知道目标 menu
记录的 ID。
目前,我执行以下操作:
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)
我想到的另一个选择是首先获取 Link 1.1 的父级,然后通过排除 Link 1.1 的 id 来获取其子级,但我正在寻找只有 1 个查询的解决方案。
最佳答案
您首先检查祖先
select *
from menu_closure a
where a.descendant = 2
然后去接 sibling
select *
from menu_closure a
join menu_closure s on s.ancestor = a.ancestor
where a.descendant = 2
与“Link 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
关于php - 如何使用 SQL 闭包表模式获取所有同级(无需子查询!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40561119/