最小节点交叉

时间:2014-12-01 21:30:02

标签: sql oracle

我有一张桌子

test (node, border)
A  B
A  C
A  E
A  F
F  C
F  D
B  S

我需要获取表单输出(node,border,num_passes)。对于。恩。从A到S,我可以进入2个十字架(A-B-S),依此类推。无法理解,如何在sql中实现递归查询

2 个答案:

答案 0 :(得分:0)

等级就是你要找的!

SELECT node,border,SYS_CONNECT_BY_PATH (node,'-') || '-' ||border,level
FROM TEST
START WITH NODE= 'A'
CONNECT BY NOCYCLE
PRIOR border = NODE;

Result:

NODE   BORDER   SYS_CONNECT_BY_PATH(NODE,'-')||'-'||BORDER    LEVEL

A      B        -A-B                                          1 
B      S        -A-B-S                                        2 
A      C        -A-C                                          1 
A      E        -A-E                                          1 
A      F        -A-F                                          1 
F      C        -A-F-C                                        2 
F      D        -A-F-D                                        2 

答案 1 :(得分:0)

/*
with tab as (
select 'A' node,  'B' border from dual
union all select 'A',  'C' from dual
union all select 'A', 'E' from dual
union all select 'A', 'F' from dual
union all select 'F', 'C' from dual
union all select 'F', 'D' from dual
union all select 'B', 'S' from dual
)
*/
select node, border, min(length(regexp_replace(s, '[^,]'))) 
from (
select node, border,
       substr(path, instr(path, ',' || node || ',') + length(node)+1, 
                    instr(path, ',' || border || ',') 
                    - instr(path, ',' || node || ',') - length(border)) s from
(select distinct t1.node, t2.border
 from tab t1 cross join tab t2) ab
 join
(select sys_connect_by_path(node, ',') || ',' || border || ',' path from tab
 connect by nocycle node = prior border) dist
 on path like '%,'|| node || ',%'
    and instr(path, ',' || node || ',') > 0
    and instr(path, ',' || node || ',') < instr(path, ',' || border || ',')
)    
group by node, border;