构造一棵完成的树的算法

业务描述:存在一棵部门树,当前的部门树(DEPT表),用户A(USERS)对树上的一些部门有访问的权限,通过一个配置模块,可以配置用户具有哪些树的节点访问权限,存储在用户部门关系表(USER_DEPTS)中,现在需要构造一棵新的树,需要将用户所有具有选择权限的树,展示出来,(将具有父子关系的节点以父子节点的形式展示出来)展示规则参考如下:

depts表的数据:

1 SELECT lpad(' ', LEVEL * 4) || t.dept_names
2   FROM depts t
3  START WITH t.parent_id = 'ROOT'
4 CONNECT BY PRIOR t.id = t.parent_id

USERS表的数据

USER_DEPTS表的数据:

 

     那么现在1用户现在有树中三个节点的访问权限,但是,A和A1构成了父子关系,所以,按照业务要求,目前构成的树的形状为十一A和C1同时作为根节点:

构建树的SQL语句:

WITH TEMP_DATA AS
 (SELECT COLS.ID,
         COLS.USER_ID,
         COLS.USER_NAME,
         COLS.DEPT_ID,
         COLS.DEPT_NAMES,
         NVL(UD.DEPT_ID, 'ROOT') AS PARENT_ID --构建树的临时父节点
    FROM (SELECT T.ID,
                 T.USER_ID,
                 U.USER_NAME,
                 T.DEPT_ID,
                 D.DEPT_NAMES,
                 D.PARENT_ID
            FROM USER_DEPT T
            LEFT JOIN USERS U
              ON T.USER_ID = U.ID
            LEFT JOIN DEPTS D
              ON T.DEPT_ID = D.ID) COLS
    --判断父节点是否也在配置表中
    LEFT JOIN USER_DEPT UD
      ON COLS.PARENT_ID = UD.DEPT_ID)
SELECT LPAD(' ', LEVEL * 4) || T.DEPT_NAMES
  FROM TEMP_DATA T
 START WITH T.PARENT_ID = 'ROOT'
CONNECT BY PRIOR T.DEPT_ID = T.PARENT_ID

--结果:

posted on 2013-02-28 21:46  Coldest Winter  阅读(707)  评论(0编辑  收藏  举报