WITH RECURSIVE DeptCTE AS (
-- 初始查询(锚点成员)
SELECT id, parentId, name
FROM departments
WHERE id = ? -- 假设?是一个占位符,用于你要查询的起始部门ID
UNION ALL
-- 递归查询(递归成员)
SELECT d.id, d.parentId, d.name
FROM departments d
INNER JOIN DeptCTE dcte ON d.parentId = dcte.id
)
SELECT * FROM DeptCTE;
在这个例子中,DeptCTE
是一个公用表表达式,它首先通过选择具有特定ID的部门作为起始点(锚点成员)。然后,它通过内部连接自己(递归成员)来选择所有具有这个起始部门作为父部门的子部门。这个过程会一直重复,直到没有更多的子部门为止。
请注意,你需要将 ?
替换为你要查询的起始部门ID的实际值,或者根据你的数据库环境使用适当的参数化查询技术。
此外,UNION ALL
用于合并两个查询的结果,包括重复行。如果你确定结果中不会有重复的行(例如,每个部门ID在表中是唯一的),你也可以使用 UNION
来代替 UNION ALL
,但 UNION
会对结果进行去重,这可能会降低查询性能。
最后,请注意,不是所有的数据库系统都支持 WITH RECURSIVE
语法。但是,大多数现代的SQL数据库系统(如PostgreSQL, MySQL 8.0+, SQLite, SQL Server, Oracle)都支持它。如果你使用的数据库系统不支持 WITH RECURSIVE
,你可能需要查找该系统的特定递归查询方法或使用存储过程来模拟递归逻辑。
<mapper namespace="com.example.mapper.DepartmentMapper">
<!-- 定义一个查询所有子部门的操作 -->
<select id="findDeptAndAllSubDepts" resultType="com.example.domain.DeptDO">
WITH RECURSIVE DeptCTE AS (
SELECT id, parentId, name
FROM departments
WHERE id = #{deptId}
UNION ALL
SELECT d.id, d.parentId, d.name
FROM departments d
INNER JOIN DeptCTE dcte ON d.parentId = dcte.id
)
SELECT * FROM DeptCTE
</select>
</mapper>