-- 查询ID为100的组织及其所有子组织的STRU_ID WITHRECURSIVE org_tree AS ( -- 锚点成员:选择初始节点 SELECT STRU_ID, PARENT_ID, STRU_TYPE, ORGAN_ALIAS, 0AS level FROM sys_stru WHERE STRU_ID =100 AND DEL_FLAG ='0'
UNIONALL
-- 递归成员:通过PARENT_ID与STRU_ID的关联获取子节点 SELECT s.STRU_ID, s.PARENT_ID, s.STRU_TYPE, s.ORGAN_ALIAS, ot.level +1 FROM sys_stru s JOIN org_tree ot ON s.PARENT_ID = ot.STRU_ID WHERE s.DEL_FLAG ='0' ) -- 最终查询结果 SELECT STRU_ID FROM org_tree ORDERBY level, STRU_ID;
这个查询的工作原理:
先查询指定的组织节点(这里是ID为100的组织)
然后通过递归,不断查找以该节点为父节点的子组织
递归过程会一直持续到找不到更多子节点为止
如果只需要组织ID列表,可以简化查询:
1 2 3 4 5 6 7 8
WITHRECURSIVE org_tree AS ( SELECT STRU_ID, PARENT_ID FROM sys_stru WHERE STRU_ID =100AND DEL_FLAG ='0' UNIONALL SELECT s.STRU_ID, s.PARENT_ID FROM sys_stru s JOIN org_tree ot ON s.PARENT_ID = ot.STRU_ID WHERE s.DEL_FLAG ='0' ) SELECT STRU_ID FROM org_tree;
2. 利用STRU_PATH字段(如果已存储路径信息)
如果表中的STRU_PATH字段存储了完整的树形编码,可以使用模糊查询更高效地获取所有子组织:
1 2 3 4 5 6 7 8 9 10
-- 先获取目标组织的STRU_PATH SET@target_path= (SELECT STRU_PATH FROM sys_stru WHERE STRU_ID =100);
-- 查询目标组织及其所有子组织 SELECT STRU_ID FROM sys_stru WHERE STRU_PATH =@target_path-- 目标组织自身 OR STRU_PATH LIKE CONCAT(@target_path, ',%') -- 所有子组织 AND DEL_FLAG ='0' ORDERBY STRU_LEVEL, STRU_ID;
-- 获取目标组织的STRU_FID SET@target_fid= (SELECT STRU_FID FROM sys_stru WHERE STRU_ID =100);
-- 查询包含目标组织ID的所有组织 SELECT STRU_ID FROM sys_stru WHERE STRU_FID =@target_fid-- 精确匹配 OR STRU_FID LIKE CONCAT(@target_fid, ',%') -- 子组织 AND DEL_FLAG ='0' ORDERBY STRU_LEVEL, STRU_ID;
4. 多次自连接查询(适用于已知层级深度)
对于层级固定且较少的情况,可以使用多次自连接:
1 2 3 4 5 6 7
-- 查询最多3层的组织结构 SELECTDISTINCT s1.STRU_ID FROM sys_stru s1 LEFTJOIN sys_stru s2 ON s1.STRU_ID = s2.PARENT_ID AND s2.DEL_FLAG ='0' LEFTJOIN sys_stru s3 ON s2.STRU_ID = s3.PARENT_ID AND s3.DEL_FLAG ='0' LEFTJOIN sys_stru s4 ON s3.STRU_ID = s4.PARENT_ID AND s4.DEL_FLAG ='0' WHERE s1.STRU_ID =100AND s1.DEL_FLAG ='0';
WITHRECURSIVE org_tree AS ( SELECT STRU_ID, PARENT_ID, IS_LEAF FROM sys_stru WHERE STRU_ID =100AND DEL_FLAG ='0'
UNIONALL
SELECT s.STRU_ID, s.PARENT_ID, s.IS_LEAF FROM sys_stru s JOIN org_tree ot ON s.PARENT_ID = ot.STRU_ID WHERE s.DEL_FLAG ='0'AND ot.IS_LEAF ='0'-- 只有非叶子节点才继续递归 ) SELECT STRU_ID FROM org_tree;
限制递归深度:对于非常大的树结构,可以限制递归深度以避免性能问题:
1 2 3 4 5 6 7 8 9 10 11
WITHRECURSIVE org_tree AS ( SELECT STRU_ID, PARENT_ID, 1AS depth FROM sys_stru WHERE STRU_ID =100AND DEL_FLAG ='0'
UNIONALL
SELECT s.STRU_ID, s.PARENT_ID, ot.depth +1FROM sys_stru s JOIN org_tree ot ON s.PARENT_ID = ot.STRU_ID WHERE s.DEL_FLAG ='0'AND ot.depth <10-- 限制最大深度为10 ) SELECT STRU_ID FROM org_tree;
五、应用场景示例
1. 获取某部门的所有员工
1 2 3 4 5 6 7 8 9 10 11 12
-- 先获取部门及其所有子部门 WITHRECURSIVE dept_tree AS ( SELECT STRU_ID FROM sys_stru WHERE STRU_ID =100AND DEL_FLAG ='0' UNIONALL SELECT s.STRU_ID FROM sys_stru s JOIN dept_tree dt ON s.PARENT_ID = dt.STRU_ID WHERE s.DEL_FLAG ='0' ) -- 然后查询这些部门中的所有员工 SELECT e.*FROM employee e JOIN dept_tree dt ON e.department_id = dt.STRU_ID WHERE e.status ='active';
2. 按层级展示组织结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
WITHRECURSIVE org_tree AS ( SELECT STRU_ID, PARENT_ID, ORGAN_ALIAS, 0AS level FROM sys_stru WHERE STRU_ID =100AND DEL_FLAG ='0'
UNIONALL
SELECT s.STRU_ID, s.PARENT_ID, s.ORGAN_ALIAS, ot.level +1 FROM sys_stru s JOIN org_tree ot ON s.PARENT_ID = ot.STRU_ID WHERE s.DEL_FLAG ='0' ) SELECT STRU_ID, CONCAT(REPEAT(' ', level), ORGAN_ALIAS) AS hierarchical_name, level FROM org_tree ORDERBY level, STRU_ID;