Sql 最小节点交叉
我有一张桌子Sql 最小节点交叉,sql,oracle,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级别实现递归查询是您需要的 SELECT node,border,SYS_CONNECT_BY_PATH (node,'-') || '-' ||border,level FROM TEST START WITH NODE= '
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级别实现递归查询是您需要的
SELECT node,border,SYS_CONNECT_BY_PATH (node,'-') || '-' ||border,level
FROM TEST
START WITH NODE= 'A'
CONNECT BY NOCYCLE
PRIOR border = NODE;
但据我所知,LEVEL将给出两个节点之间的所有可能路径,我如何找到最小路径?例如,在结果表中,从F到C,它是2,但应该是1。这是我实际需要的东西,但当我尝试对实际数据运行此查询时,大约是200行*2列。在每个单元格中有两个字符的varchar。它汇集了无穷的信息
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
/*
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;