您现在的位置是:首页 >其他 >oracle connect by 学习网站首页其他
oracle connect by 学习
【Connect by 层次查询】 https://www.bilibili.com/video/BV1jV411t7CB/?share_source=copy_web&vd_source=d88a617727cccf1c106d623afec0c6b6
简单来说这个connect by 就是为了查父子节点的。
CREATE TABLE test.emp (id varchar(10),name varchar(10),manager_id varchar(10));
INSERT INTO test.emp
select 1,'小明',NULL from dual union all
select 2,'小李',1 from dual union all
select 3,'小张',1 from dual union all
select 4,'小王',2 from dual union all
select 5,'小周',4 from dual union all
select 6,'小赵',3 from dual union all
select 7,'小吴',3 from dual
下面来学习connect by的语法。
首先我们查父子关系,需要明确两点!!
1. 从哪个节点查询,比如上面 我们是从老板开始 还是经理开始,还是从员工开始
2.节点之间的关系是什么? 比如从经理开始 我们是要查经理的manger还是经理下面的employer
由此引发出语法。
1 start with
从哪条数据开始 start with id =1 / start with id in (2,3)
2. connect by
连接关系肯定是 id =manger_id 但是这个如何表表示我们想查manger还是employer呢?
由此引出了一个关键字 prior
prior id =manger_id 代表父节点的id = 子节点的manager_id 也就是我们从老板查经理查员工
prior manger_id=id 代表父节点的manager_id=子节点的id,从员工查经理查老板
简单的理解prior英文=先前的 所以先前的就代表 startwith的哪些条件,start with 不是确定哪个人了吗? 所以就是
prior id =manger_id那个人的id = 其他人的manger_id 就是往下查询
以该图为例 我们开始从小明查 所以 start with name='小明'
查小明的下属 也就是 小明的 id=其他的 manger_id -> prior id =manger_id
SELECT *
FROM test.emp
START WITH name ='小明'
CONNECT BY PRIOR id=manager_id
看着好像很不起眼,和之前的select *没有区别,但是是有区别的。但确实区别不大,
为了让人更加直观的看出结果此时再次引出一个关键字
level
上面的树状图中 小明处在第一层级,小张小李出在第二层级,这样很容易区分哪些数据处于同一层级
SELECT t.*,LEVEL
FROM test.emp t
START WITH name ='小明'
CONNECT BY PRIOR id=manager_id
这个图虽然表表示了层级关系,但是对于小明下面的层级关系还是不太清晰,假设表里数据有几十万条,最终的老板也有好几个,有可能员工a处于第10层级,我们怎么快速的判断a的老板是谁呢?
1.按照以前的方式 a的上一层经理是a1,在查a1的上层经理是a2,继续查a3,查a4.。。。
2.根据刚刚学的 start with name='a' connect by prior manager_id=id
3. 引出一个方法
sys_connect_by_path
看这个方法名就可以看出来,肯定和connect有关,by_path,代表把所有路径的数据都整合起来。
SELECT t.*,LEVEL ,SYS_CONNECT_BY_PATH(name ,'->')
FROM test.emp t
START WITH name ='小明'
CONNECT BY PRIOR id=manager_id
最终的结果 也很好看 ->小明->小李->小王->小周 很清晰的表明了层级关系。
--------------------------------------------------------------
再说一说 connect by 的其他用法。
1.构造序列
SELECT LEVEL FROM dual CONNECT BY LEVEL<5
2.制造测试数据
select rownum as id,
to_char(sysdate + rownum / 24 / 3600, 'yyyy-mm-dd hh24:mi:ss') as inc_datetime,
trunc(dbms_random.value(0, 100)) as random_id,
dbms_random.string('x', 20) random_string
from dual
connect by level <= 10; --想要多少条就有多少条
还有什么排列组合 啥用没有 不说了