十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
select SYS_CONNECT_BY_PATH(列名,'') from 表名
专注于为中小企业提供网站建设、成都网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业寒亭免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上千企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
start wITh 列名='0000000001'
connect by prior 列名(孩子列所有的列名)=列名(父列所有的列名)
这个查出来的样式如下:
000000000001000000000000
不知道是不是你想要的。
可以设计成有层级的序列号,最顶级找0101就可以了
no id_sj id_bj jc
000 01 1
001 01 0101 2
002 0101 010101 3
003 010101 01010101 4
如何结构不能变,还是如下方式,而且当前层级是几级都不知道,就用循环吧
PS:001怎么还有上级编码1?到底顶级在哪里?
no id_sj id_bj
001 1 2
002 2 3
003 3 4
v_id_bj:=4;
while v_id_sj is not null loop
select id_sj into v_id_sj from tb where id_bj = v_id_bj;
select id_bj into v_id_bj from tb where id_bj = v_id_sj;
end loop;
1、创建测试表,create table test_connect(id number, p_id number);
2、插入测试数据,
insert into test_connect values(1,1);
insert into test_connect values(2,1);
insert into test_connect values(3,2);
insert into test_connect values(4,3);
commit;
3、查询数据表内容,select * from test_connect ,
4、执行递归查询语句,加入nocycle要素,不会出现【ORA-01436: 用户数据中的 CONNECT BY 循环的错误】,执行结果如下,
select *
from test_connect t
start with id = 4
connect by nocycle prior t.p_id = t.id
我感觉你应该分两步走,第一找到父节点,第二,将这些父节点加上条件。不知道你的父节点和叶子节点是怎么存储到表中的,我举一个父节点和叶子节点存储在一个表中的情况给你说一下。
第一步,找到所有父节点 select 父节点 from table_A where table_A.isdetail1(意思是说,父节点不是明细项)
第二步,找到叶子节点的父节点:select 父节点 from table_A where table_A.isdetail1 and table_A.叶子节点 in(叶子节点)
第三步,再加上条件:找到叶子节点的父节点:select 父节点 from table_A where table_A.isdetail1 and table_A.叶子节点 in(叶子节点)and 父节点不符合哪些条件。
一般来说这种递归查询应该用start with connect by,不过你的表中少了一列,就是当前节点的父节点列,所以这个应该不能用。
比如元数据为4列 其中两列类似为
父节点编码 当前节点编码
010001000000 010001010000
010001010000 010001010200
那么start with connect by就可以用了,这里因为没有这个父节点编码的字段,所以不能用。
那么查询就麻烦一些,我想到了一个办法,不过是这个表结构的特例,希望能帮到你
第一步是截取输入的diccode的非零长度,我想到的办法是length(trim(tailing 0 from '输入或计算得到的diccode值'))--假设得到的是8位,假设为01000101 8位
那么所有的子节点就是 diccode like substr(diccode,1,length(trim(tailing 0 from '输入或计算得到的diccode值')))%
意思就是 diccode like '01000101%'(这不就是所有该节点的子节点了么,包括自身)
(以上部分的写法要斟酌一下,%是通配符,一般来说我们的写法是like ‘a%’,但是单引号部分怎么写,需不需要转译,反引号行不行,与%怎么连接,我没有环境只能写个大概意思,具体的要试验才行。)
然后求父节点,先求上一级,diccode=(case when length(trim(tailing 0 from '输入或计算得到的diccode值'))-20 then rpad(substr('输入或计算得到的diccode值',1, length(trim(tailing 0 from '输入或计算得到的diccode值'))-2),12,0) else 0 end)
意思就是:截取到01000101后,长度为8位,长度-2为6位那么就是010001,然后补足12位的0,为010001000000,也就是上一级父节点。如果输入为010000000000,那么第一步就直接查出所有内容了,后面这个条件用or连接,查出来的都是0,也就是diccode=0,不会干扰正常内容的显示。
然后继续-2变成-4(这样举例就变成为010000000000),再变成-6(例子中虽然也能查出来010000000000,但是前面已经查出,不会重复显示的),-8(例子中等于0,那么显示diccode=0,因为or连接所以不耽误显示),-10,我看了你的编码是12位,-10应该够了,写法同上,然后所有的条件用or连接,这样不用写过程去计算,虽然麻烦,而且速度不会太快,但是思路应该没错。
其实我一直在琢磨应该可以用start with connect by写后面的-2到-10部分,但是如果写成start那么这部分需要测试,我这里没有相关的环境,所以只能是这么写,麻烦一些。而且starwith好像没办法就相关子节点,所以我也不知道到底能不能用。
假设这个表名为A
select * from A START WITH id in
(select distinct id from A )
CONNECT BY PRIOR oid=id
oracle 10g之前执行这条语句,好像oid不能为空,你可以将id为1那条数据oid栏位设置为1或者别的,反正不要是里面有的节点的id就行了