Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 最小节点交叉_Sql_Oracle - Fatal编程技术网

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;