select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
select ... start with initial-condition connect by nocycle recurse-condition
select ... connect by recurse-condition
recurse-condition can make use of the keyword prior: connect by
prior foo = bar
set feedback off
create table test_connect_by (
parent number,
child number,
constraint uq_tcb unique (child)
);
insert into test_connect_by values ( 5, 2);
insert into test_connect_by values ( 5, 3);
insert into test_connect_by values (18,11);
insert into test_connect_by values (18, 7);
insert into test_connect_by values (17, 9);
insert into test_connect_by values (17, 8);
insert into test_connect_by values (26,13);
insert into test_connect_by values (26, 1);
insert into test_connect_by values (26,12);
insert into test_connect_by values (15,10);
insert into test_connect_by values (15, 5);
insert into test_connect_by values (38,15);
insert into test_connect_by values (38,17);
insert into test_connect_by values (38, 6);
insert into test_connect_by values (null, 38);
insert into test_connect_by values (null, 26);
insert into test_connect_by values (null, 18);
select lpad(' ',2*(level-1)) || to_char(child) s
from test_connect_by
start with parent is null
connect by prior child = parent;
38
15
10
5
2
3
17
9
8
6
26
13
1
12
18
11
7
start with ... connect by
select statement be read and interpreted? If Oracle encounters such an
SQL statement, it proceeds as described in the following pseude code. for rec in (select * from some_table) loop
if FULLFILLS_START_WITH_CONDITION(rec) then
RECURSE(rec, rec.child);
end if;
end loop;
procedure RECURSE (rec in MATCHES_SELECT_STMT, new_parent IN field_type) is
begin
APPEND_RESULT_LIST(rec);
for rec_recurse in (select * from some_table) loop
if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child, new_parent) then
RECURSE(rec_recurse,rec_recurse.child);
end if;
end loop;
end procedure RECURSE;
create table prune_test (
parent number,
child number
);
insert into prune_test values (null, 1);
insert into prune_test values (null, 6);
insert into prune_test values (null, 7);
insert into prune_test values ( 1, 12);
insert into prune_test values ( 1, 14);
insert into prune_test values ( 1, 15);
insert into prune_test values ( 6, 61);
insert into prune_test values ( 6, 63);
insert into prune_test values ( 6, 65);
insert into prune_test values ( 6, 69);
insert into prune_test values ( 7, 71);
insert into prune_test values ( 7, 74);
insert into prune_test values ( 12, 120);
insert into prune_test values ( 12, 124);
insert into prune_test values ( 12, 127);
insert into prune_test values ( 65, 653);
insert into prune_test values ( 71, 712);
insert into prune_test values ( 71, 713);
insert into prune_test values ( 71, 715);
insert into prune_test values ( 74, 744);
insert into prune_test values ( 74, 746);
insert into prune_test values ( 74, 748);
insert into prune_test values ( 712,7122);
insert into prune_test values ( 712,7125);
insert into prune_test values ( 712,7127);
insert into prune_test values ( 748,7481);
insert into prune_test values ( 748,7483);
insert into prune_test values ( 748,7487);
select
lpad(' ', 2*level) || child
from
prune_test
start with
parent is null
connect by
prior child=parent
and parent not in (1, 71);
1
6
61
63
65
653
69
7
71
74
744
746
748
7481
7483
7487
set feedback off
drop table parent_child;
create table parent_child(parent_ varchar2(20), child_ varchar2(20));
insert into parent_child values (null, 'a')
insert into parent_child values ( 'a', 'af');
insert into parent_child values ( 'a', 'ab');
insert into parent_child values ( 'a', 'ax');
insert into parent_child values ( 'ab', 'abc');
insert into parent_child values ( 'ab', 'abd');
insert into parent_child values ( 'ab', 'abe');
insert into parent_child values ('abe','abes');
insert into parent_child values ('abe','abet');
insert into parent_child values ( null, 'b');
insert into parent_child values ( 'b', 'bg');
insert into parent_child values ( 'b', 'bh');
insert into parent_child values ( 'b', 'bi');
insert into parent_child values ( 'bi', 'biq');
insert into parent_child values ( 'bi', 'biv');
insert into parent_child values ( 'bi', 'biw');
set verify off
select
case when count(*) > 0 then
'&&parent is an ancestor of &&child' else
'&&parent is no ancestor of &&child' end
"And here's the answer"
from
parent_child
where
child_ = '&&child'
start with
parent_ = '&&parent'
connect by
prior child_ = parent_;
undefine child
undefine parent
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/18921899/viewspace-1016971/ ,如需转载,请注明出处,否则将追究法律责任。