Hierarchical Queries—组织部门关系整理

前言:
写了一堆的java代码,现在发现,解决这个问题的最好的手段是用sql中的Hierarchical Queries(层级查询)
参考Hierarchical Queries: https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm

-3 start with 的条件从其他表动态获取的方法

用先连接后start with 的办法
http://www.itpub.net/thread-1710588-1-1.html
类似这种

--  先连接 再追溯
select addr.*,a.id ,a.DEPT_ID
from BI_TRADE_INFO addr,SYS_P_DEPARTMENT_3   a
where 1=1
start with addr.dept_id=a.id
connect by a.id=prior a.parent_id

-2 只提取一条链 用start with

在这里插入图片描述

-1 原理

利用递归查询的方法实现的,所以最后查询的结果数量会增多,如下面这个例子,表中只有3条数据,查询结果编程了6条。
在这里插入图片描述

0 关于prior

通俗的来讲就是 ,超前看 还是朝后看
在这里插入图片描述

1 语法

下面这张表

LAST_NAME                 EMPLOYEE_ID MANAGER_ID      LEVEL
------------------------- ----------- ---------- ----------
King                              100                     1
Cambrault                         148        100          2
Bates                             172        148          3
Bloom                             169        148          3
Fox                               170        148          3
Kumar                             173        148          3
Ozer                              168        148          3
Smith                             171        148          3
De Haan                           102        100          2
Hunold                            103        102          3
Austin                            105        103          4
Ernst                             104        103          4
Lorentz                           107        103          4
Pataballa                         106        103          4
Errazuriz                         147        100          2
Ande                              166        147          3
Banda                             167        147          3
SELECT last_name "Employee", CONNECT_BY_ISCYCLE "Cycle",  //这是一个循环伪列
   LEVEL, SYS_CONNECT_BY_PATH(last_name, '/') "Path"
   FROM employees
   WHERE level <= 3     //层级
   START WITH last_name = 'King'   //以king 为祖宗节点 如果没有 可以有多个根节点
   CONNECT BY NOCYCLE PRIOR employee_id = manager_id AND LEVEL <= 4;   //NOCYCLE 表示就算有循环
   也要显示出来

Employee                   Cycle  LEVEL Path
------------------------- ------ ------ -------------------------
Russell                        1      2 /King/Russell
Tucker                         0      3 /King/Russell/Tucker
Bernstein                      0      3 /King/Russell/Bernstein
Hall                           0      3 /King/Russell/Hall
Olsen                          0      3 /King/Russell/Olsen
Cambrault                      0      3 /King/Russell/Cambrault
Tuvault                        0      3 /King/Russell/Tuvault
Partners                       0      2 /King/Partners
King                           0      3 /King/Partners/King
Sully                          0      3 /King/Partners/Sully
McEwen                         0      3 /King/Partners/McEwen
...
CONNECT_BY_ROOT Examples 

2 实例

2.1 实例一:组织部门关系 :

1.导入到数据库中
2.用下列的sql语句进行查询

我的理解
1层级关系,本意是想生成一个树,根是不能有多个的,你可以自己设置根,也就是开始的点,如果不是顶级节点,就可能是树的一部分,里面可能有数据就没没用了。
2如果层次关系不是一棵树就有可能出现循环的问题,然后就需要用 NOCYCLE 这个关键词 ,另外为了显示,循环的结果集,可以用 CONNECT_BY_ISCYCLE “Cycle” ,他会记录循环的记录
3下面就是一个有循环的组织关系

 select ia.id,name,IA.PARENT_ID,level, CONNECT_BY_ISCYCLE "Cycle" from  SYS_P_DEPARTMENT ia CONNECT
  BY  NOCYCLE prior ia.id=ia.parent_id ORDER BY "Cycle" ;
3 结果

这里写图片描述

2.2 实例二 投稿排行根据顶级部门统计数量

出自:https://blog.csdn.net/crzzyracing/article/details/75216431
    找出编号为101的雇员及其所有上司  
    
        select level, t.*
          from myemp t
         start with employee_id = 101
        connect by employee_id = prior manager_id;

        别人的工号 = 我的经理编号 ---> 别人是我的经理 & 别人是我经理的经理 ---> 我的所有上司

工会查找顶级部门

select ia.id,name,IA.PARENT_ID,level, CONNECT_BY_ISCYCLE "Cycle" from  SYS_P_DEPARTMENT ia 
START WITH id = 533
CONNECT BY  NOCYCLE   ia.id=prior ia.parent_id ORDER SIBLINGS BY id ;

在这里插入图片描述

2.3实例三 组织部门三级结构

SELECT c.id id1,c.name name1,t.id1 id2,t.name1 name2,t.id2 id3,t.name2 name3 FROM
SYS_P_DEPARTMENT c
LEFT JOIN
(
SELECT
	A.id id1,A."NAME" name1,a.PARENT_ID id2,b."NAME" name2
FROM
	"SYS_P_DEPARTMENT" A
LEFT JOIN "SYS_P_DEPARTMENT" B ON A .PARENT_ID = B.id
)t
on c.parent_id=t.id1

在这里插入图片描述

2.4 查找爸爸 和 爷爷的例子

这个需求是因为相同工会的不同部门之间需要可以相互审核,所以加上这个,只要父辈有一个匹配就认为是同一个部门的。


with tmp as(
      select a.*, level leaf        
      from SYS_P_DEPARTMENT_3 a  
START with   a.id='373'
-- 			where a.parent_id is not NULL
      connect by prior a.parent_id = a.id )
select *                               
from tmp                             
where leaf = 2 or  leaf = 3 or  leaf = 1;  //跟自己相同或者有共同的父辈就是一个工会的

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值