MySQL树形查询主要用于处理具有层次结构的数据,例如组织结构、分类目录等。常见的树形查询方法包括递归查询、嵌套集模型和路径枚举等。
假设我们有一个表 employees
,其中包含员工的ID、姓名和上级ID:
CREATE TABLE employees (
id INT PRIMARY KEY,
name VARCHAR(100),
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);
使用CTE进行递归查询:
WITH RECURSIVE employee_tree AS (
SELECT id, name, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, et.level + 1
FROM employees e
INNER JOIN employee_tree et ON e.manager_id = et.id
)
SELECT * FROM employee_tree;
嵌套集模型通过左右值来表示树的层次结构。假设我们有一个表 categories
:
CREATE TABLE categories (
id INT PRIMARY KEY,
name VARCHAR(100),
lft INT,
rgt INT
);
插入一些示例数据:
INSERT INTO categories (id, name, lft, rgt) VALUES
(1, 'Electronics', 1, 12),
(2, 'Computers', 2, 7),
(3, 'Laptops', 3, 6),
(4, 'Desktops', 4, 5),
(5, 'Smartphones', 8, 11),
(6, 'Apple', 9, 10);
查询某个节点的所有后代:
SELECT child.*
FROM categories AS parent, categories AS child
WHERE child.lft BETWEEN parent.lft AND parent.rgt
AND parent.name = 'Electronics'
ORDER BY child.lft;
原因:递归查询可能导致大量的重复计算,尤其是在树结构较深时。
解决方法:
manager_id
字段上创建索引。WITH RECURSIVE employee_tree AS (
SELECT id, name, manager_id, 1 AS level
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, e.manager_id, et.level + 1
FROM employees e
INNER JOIN employee_tree et ON e.manager_id = et.id
WHERE et.level < 10 -- 限制递归深度
)
SELECT * FROM employee_tree;
通过以上方法,可以有效提升树形查询的性能和稳定性。
领取专属 10元无门槛券
手把手带您无忧上云