要高效查询MySQL中指定部门及其所有子部门下的所有员工,通常需要处理层级结构的部门数据。假设你的部门表(departments)和员工表(employees)结构如下:
departments 表:
id:部门IDname:部门名称parent_id:上级部门ID(根部门的 parent_id 为 NULL 或 0)employees 表:
id:员工IDname:员工名称department_id:所属部门ID使用递归CTE(Common Table Expressions): MySQL 8.0及以上版本支持递归CTE,可以方便地处理层级结构数据。
WITH RECURSIVE DepartmentTree AS (
-- 基础查询:选择指定部门
SELECT id, name, parent_id
FROM departments
WHERE id = ? -- 替换为指定的部门ID
UNION ALL
-- 递归查询:选择所有子部门
SELECT d.id, d.name, d.parent_id
FROM departments d
INNER JOIN DepartmentTree dt ON d.parent_id = dt.id
)
-- 查询所有员工
SELECT e.*
FROM employees e
INNER JOIN DepartmentTree dt ON e.department_id = dt.id;
解释:
WITH RECURSIVE DepartmentTree AS (...):定义一个递归CTE,用于获取指定部门及其所有子部门。INNER JOIN 连接 departments 表和 DepartmentTree,获取所有子部门。INNER JOIN 连接 employees 表和 DepartmentTree,获取所有员工。使用嵌套集模型(Nested Set Model):
如果你的部门表使用了嵌套集模型(即每个部门有 left 和 right 字段来表示层级关系),查询会更加高效。
SELECT e.*
FROM employees e
INNER JOIN departments d ON e.department_id = d.id
WHERE d.left BETWEEN (SELECT left FROM departments WHERE id = ?)
AND (SELECT right FROM departments WHERE id = ?);
解释:
d.left BETWEEN ... AND ...:通过 left 和 right 字段来确定指定部门及其所有子部门的范围。left 和 right 字段。使用路径枚举模型(Path Enumeration Model):
如果部门表使用了路径枚举模型(即每个部门有一个 path 字段,存储从根部门到当前部门的路径),查询也可以高效进行。
SELECT e.*
FROM employees e
INNER JOIN departments d ON e.department_id = d.id
WHERE d.path LIKE CONCAT((SELECT path FROM departments WHERE id = ?), '%');
解释:
d.path LIKE ...:通过 path 字段来匹配指定部门及其所有子部门。path 字段。left 和 right 字段。path 字段。根据你的数据库设计和MySQL版本,选择最适合的方案。