php - 如何使用 SQL 闭包表模式获取所有同级(无需子查询!)

标签 php mysql tree

我正在尝试为一个简单的菜单模型实现闭包表模式,但是在构建查询以查找当前节点的所有兄弟节点没有子查询时遇到了一些困难(例如,使用加入)。

有一个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

最终sqlfiddle

关于php - 如何使用 SQL 闭包表模式获取所有同级(无需子查询!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40561119/

相关文章:

tree - 如何在 TreePanel 中插入新记录(模型)?

c - 对于这两种情况,C 中的最佳数据结构?

java - 绘制一个java类的依赖关系图

php - preg_match 多个单词

php - 从php字符串中提取特定数据

MySQL - 选择除 1 以外的所有不同行

mysql - 提取 Customer_Order 表中不存在的产品 ID

php - 合并两个排序的数组,结果数组也应该排序

javascript - 通过php加载HTML表单然后使用JQuery提交表单

java - MySQL 的PreparedStatement 空指针异常