在关系型数据库中,用自连接(Self Join)实现树形结构是非常常见的做法。核心思想是:同一张表里的“子节点”通过某个字段(如 parent_id)关联到“父节点”。
下面从 表结构 → 基础自连接 → 多级树 → 常见场景 给你讲清楚。
CREATE TABLE dept (
id INT PRIMARY KEY,
name VARCHAR(50),
parent_id INT
);
示例数据:
| id | name | parent_id |
|---|---|---|
| 1 | 公司 | NULL |
| 2 | 技术部 | 1 |
| 3 | 产品部 | 1 |
| 4 | 后端组 | 2 |
| 5 | 前端组 | 2 |
SELECT
p.id AS parent_id,
p.name AS parent_name,
c.id AS child_id,
c.name AS child_name
FROM dept p
JOIN dept c
ON c.parent_id = p.id;
✅ 结果:
| parent_name | child_name |
|---|---|
| 公司 | 技术部 |
| 公司 | 产品部 |
| 技术部 | 后端组 |
| 技术部 | 前端组 |
SELECT
g.name AS grand_parent,
p.name AS parent,
c.name AS child
FROM dept g
JOIN dept p ON p.parent_id = g.id
JOIN dept c ON c.parent_id = p.id;
✅ 适合固定层级(如 3 层组织架构)
SELECT *
FROM dept
WHERE parent_id = 2;
SELECT p.*
FROM dept c
JOIN dept p ON c.parent_id = p.id
WHERE c.id = 4;
SELECT p.name
FROM dept c
JOIN dept p ON c.parent_id = p.id
WHERE c.id = 5;
如果是 MySQL 8+,更推荐用 递归 CTE:
WITH RECURSIVE t AS (
SELECT * FROM dept WHERE id = 5
UNION ALL
SELECT d.* FROM dept d
JOIN t ON d.id = t.parent_id
)
SELECT * FROM t;
| 方式 | 适合场景 |
|---|---|
| 自连接 | 层级固定(2~3层) |
| 递归 CTE | 层级不固定、无限层级 |
| 闭包表 / 路径字段 | 查询频繁、写入少 |
✅ 自连接做树形结构的核心:
同一张表,用 parent_id 关联自己
如果你用的是 MySQL / Oracle / PostgreSQL,或者想做:
可以告诉我具体场景,我可以直接给你 SQL。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。