说是递归,该执行过程更像是广度优先遍历!
sqlCREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(50),
manager_id INT
);
INSERT INTO employees (id, name, manager_id) VALUES
(1, 'Alice', NULL),
(2, 'Bob', 1),
(3, 'Charlie', 1),
(4, 'David', 2),
(5, 'Eve', 2),
(6, 'Frank', 3);
找出所有员工及其上级
sqlWITH RECURSIVE org_structure AS (
-- 初始成员:根节点(没有上级的员工)
SELECT id, name, manager_id
FROM employees
WHERE manager_id IS NULL
UNION ALL
-- 递归成员:当前节点的所有下级
SELECT e.id, e.name, e.manager_id
FROM employees e
INNER JOIN org_structure os ON os.id = e.manager_id
)
SELECT * FROM org_structure;
递归 CTE 的执行过程分为两个主要部分:初始成员和递归成员。
首先,执行 CTE 的初始成员部分:
sqlSELECT id, name, manager_id
FROM employees
WHERE manager_id IS NULL
这将选择所有没有上级的员工。在我们的示例中,只有 Alice 没有上级:
sqlid | name | manager_id
---|-------|------------
1 | Alice | NULL
接下来,执行递归成员部分,将初始成员作为输入:
sqlSELECT e.id, e.name, e.manager_id
FROM employees e
INNER JOIN org_structure os ON os.id = e.manager_id
第一次递归:使用初始成员(Alice)的结果。查找所有上级为 Alice 的员工:
sqlid | name | manager_id
---|---------|------------
2 | Bob | 1
3 | Charlie | 1
第二次递归:使用第一次递归的结果(Bob 和 Charlie)。查找所有上级为 Bob 和 Charlie 的员工:
sqlid | name | manager_id
---|-------|------------
4 | David | 2
5 | Eve | 2
6 | Frank | 3
第三次递归:使用第二次递归的结果(David、Eve 和 Frank)。查找所有上级为 David、Eve 和 Frank 的员工。这次没有更多员工,因此递归停止。
将初始成员和所有递归成员的结果合并,得到最终的组织结构:
sqlid | name | manager_id
---|---------|------------
1 | Alice | NULL
2 | Bob | 1
3 | Charlie | 1
4 | David | 2
5 | Eve | 2
6 | Frank | 3
是的:
本文作者:jdxj
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!