我正在使用Oracle 10。
我有描述图表节点和路径的数据。 我想建立一个查询来描述端点之间的所有路由及其价值或遍历成本。
示例数据:
NodeId1 NodeId2 Endpoint1 Endpoint2 Value
1170 8406 34210 (null) 39
8411 8410 (null) 34260 1
8411 4275 (null) 32231 60
8406 8405 (null) 34287 1
8406 8411 (null) (null) 26
这描述了一个如下图所示(成本在括号中,端点是方括号):
1170 8406 8405
[]-----------------o----------------[]
(39) | (1)
|
|(27)
| 4275
8411 o----------------[]
| (60)
|
(1)|
|
[]
8410
输出应如下所示:
Start End Cost
1170 4275 126
1170 8405 40
1170 8410 67
8405 4275 88
8405 8410 29
4275 8410 61
我真的不需要输出两种方式(1170到8406和8406到1170),但它可以帮助进一步使用结果,所以如果它可以包含,它会很好。
答案 0 :(得分:0)
Oracle安装程序:
CREATE FUNCTION sum_Number_List(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN NUMBER DETERMINISTIC
AS
p_result NUMBER := 0;
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result := p_result + TO_NUMBER( SUBSTR( i_str, p_start, p_end - p_start ) );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result := p_result + TO_NUMBER( SUBSTR( i_str, p_start, c_len - p_start + 1 ) );
END IF;
END IF;
RETURN p_result;
END;
/
CREATE TABLE table_name ( NodeId1, NodeId2, Endpoint1, Endpoint2, Value ) AS
SELECT 1170, 8406, 34210, null, 39 FROM DUAL UNION ALL
SELECT 8411, 8410, null, 34260, 1 FROM DUAL UNION ALL
SELECT 8411, 4275, null, 32231, 60 FROM DUAL UNION ALL
SELECT 8406, 8405, null, 34287, 1 FROM DUAL UNION ALL
SELECT 8406, 8411, null, null, 26 FROM DUAL;
<强>查询强>:
WITH directedgraph AS (
SELECT NodeID1 AS f,
NodeID2 AS t,
EndPoint1 AS isStart,
EndPoint2 AS isEnd,
Value
FROM table_Name
UNION ALL
SELECT NodeID2 AS f,
NodeID1 AS t,
EndPoint2 AS isStart,
EndPoint1 AS isEnd,
Value
FROM table_Name
)
SELECT CONNECT_BY_ROOT( f ) AS "START",
t AS "END",
SUM_NUMBER_LIST( SUBSTR( SYS_CONNECT_BY_PATH( value, ',' ), 2 ) ) AS cost
FROM directedgraph
WHERE CONNECT_BY_ISLEAF = 1
AND isEnd IS NOT NULL
START WITH isStart IS NOT NULL
CONNECT BY NOCYCLE
PRIOR t = f
AND PRIOR f <> t;
<强>输出强>:
START END COST
---------- ---------- ----------
1170 8405 40
1170 4275 125
1170 8410 66
4275 1170 125
4275 8405 87
4275 8410 61
8405 1170 40
8405 4275 87
8405 8410 28
8410 4275 61
8410 1170 66
8410 8405 28