MySQL递归查询上级和下级
在MySQL数据库中,我们经常需要处理具有层级关系的数据。有时候,我们需要查询一个节点的所有上级节点或者所有下级节点。这时候,递归查询就派上用场了。
本篇文章将为你介绍如何在MySQL中实现递归查询上级和下级节点,并提供相应的代码示例。
数据准备
首先,我们需要准备一个示例数据表来演示递归查询。我们将创建一个名为departments
的表,用于存储部门的层级关系。
CREATE TABLE departments (
id INT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
parent_id INT,
FOREIGN KEY (parent_id) REFERENCES departments(id)
);
INSERT INTO departments (id, name, parent_id) VALUES
(1, '总公司', NULL),
(2, '技术部', 1),
(3, '市场部', 1),
(4, '开发部', 2),
(5, '测试部', 2),
(6, '销售部', 3),
(7, '客服部', 3),
(8, '前端开发组', 4),
(9, '后端开发组', 4),
(10, '自动化测试组', 5),
(11, '手动测试组', 5),
(12, '售前部', 6),
(13, '售后部', 6),
(14, '投诉部', 7);
上面的代码创建了一个名为departments
的表,并插入了一些示例数据。每个部门都有一个唯一的id
,一个name
,以及一个可选的parent_id
,用于表示其上级部门。根节点的parent_id
字段为空。
查询下级节点
要查询某个节点的所有下级节点,我们可以使用递归查询。递归查询的基本思想是通过自连接表来迭代查询。下面是一个查询部门id
为2(技术部)的所有下级节点的示例:
WITH RECURSIVE sub_departments AS (
SELECT id, name, parent_id
FROM departments
WHERE id = 2
UNION ALL
SELECT d.id, d.name, d.parent_id
FROM departments d
JOIN sub_departments sd ON d.parent_id = sd.id
)
SELECT * FROM sub_departments;
上面的代码中,我们使用了WITH RECURSIVE
语句来定义一个递归查询的公共表表达式(CTE)。在CTE中,我们首先选择了部门id
为2(技术部)的节点作为起始点,然后通过自连接查询出所有下级节点。查询结果包含了所有的下级节点。
运行以上代码,你将会得到如下查询结果:
| id | name | parent_id |
|----|------------|-----------|
| 2 | 技术部 | 1 |
| 4 | 开发部 | 2 |
| 5 | 测试部 | 2 |
| 8 | 前端开发组 | 4 |
| 9 | 后端开发组 | 4 |
从结果中可以看出,部门id
为2(技术部)的所有下级节点被正确地查询出来。
查询上级节点
要查询某个节点的所有上级节点,我们可以使用反向递归查询。反向递归查询的思想与递归查询类似,只是查询方向相反。下面是一个查询部门id
为9(后端开发组)的所有上级节点的示例:
WITH RECURSIVE parent_departments AS (
SELECT id, name, parent_id
FROM departments
WHERE id = 9
UNION ALL
SELECT d.id, d.name, d.parent_id
FROM departments d
JOIN parent_departments pd ON d.id = pd.parent_id
)
SELECT * FROM parent_departments;
以上代码中,我们同样使用了WITH RECURSIVE
语句来定义一个递归查询的公共表表达式(CTE)。在CTE中,我们首先选择了部门id
为9(后端开发组)的节点作为起始点,然后通过反向自连接查询出所有