总距离以及SYS_CONNECT_BY_PATH

时间:2019-08-31 18:01:31

标签: sql oracle oracle11g

以关于this的问题作为参考,输入图形表为-

P_FROM      P_TO     DISTANCE
A           B         4
A           C         7
B           C        10
C           D        15
B           D        17
A           D        23
B           E        22
C           E        29

期望的答案是-

P_FROM    P_TO     FULL_ROUTE     TOTAL_DISTANCE
A         E        A->B->E        26
A         E        A->C->E        36
A         E        A->B->C->E     43

答案中给出的查询正在成功检索结果-

WITH multiroutes (p_from, p_to, full_route, total_distance)
        AS (SELECT p_from,
                   p_to,
                   p_from || '->' || p_to full_route,
                   distance total_distance
              FROM graph
             WHERE p_from LIKE 'A'
             UNION ALL
            SELECT M.p_from,
                   n.p_to,
                   M.full_route || '->' || n.p_to full_route,
                   M.total_distance + n.distance total_distance
              FROM multiroutes M JOIN graph n ON M.p_to = n.p_from
             WHERE n.p_to <> ALL (M.full_route))
     SELECT *
       FROM multiroutes
      WHERE p_to LIKE 'E'
   ORDER BY p_from, p_to, total_distance ASC;

我认为通过使用ORACLE语法,该查询可能会更加简化,因此在尝试以某种方式设法获得预期结果时,但distance列不正确-

SELECT CONNECT_BY_ROOT(P_FROM) P_FROM
      ,P_TO
      ,CONNECT_BY_ROOT(P_FROM) || SYS_CONNECT_BY_PATH(P_TO, '->') FULL_ROUTE
      ,DISTANCE TOTAL_DISTANCE
FROM graph
WHERE P_TO = 'E'
START WITH P_FROM = 'A'
CONNECT BY PRIOR P_TO = P_FROM
ORDER BY P_FROM, P_TO, TOTAL_DISTANCE ASC;

输出-

P_FROM  P_TO    FULL_ROUTE  TOTAL_DISTANCE
A       E       A->B->E     22
A       E       A->C->E     29
A       E       A->B->C->E  29

我尝试使用this中给出的类似答案的查询,但这对我没有太大帮助。是否有任何方法仅使用ORACLE特定语法来获得正确的total_distance。

Here是供您参考的小提琴。

1 个答案:

答案 0 :(得分:2)

您快完成了-您的问题是仅输出最后一步的距离。

简单地使用total_distance连接表达式+,然后按照建议的{{3}使用xmlquery 评估 }

with dist as (  
SELECT CONNECT_BY_ROOT(P_FROM) P_FROM
      ,P_TO
      ,CONNECT_BY_ROOT(P_FROM) || SYS_CONNECT_BY_PATH(P_TO, '->') FULL_ROUTE
      ,DISTANCE TOTAL_DISTANCE,
      SYS_CONNECT_BY_PATH(DISTANCE,'+')   total_distance_expr
FROM graph
WHERE P_TO = 'E'
START WITH P_FROM = 'A'
CONNECT BY PRIOR P_TO = P_FROM)
select P_FROM, P_TO, FULL_ROUTE, TOTAL_DISTANCE_EXPR
,xmlquery(TOTAL_DISTANCE_EXPR returning content).getNumberVal() as TOTAL_DISTANCE 
from dist
ORDER BY P_FROM, P_TO, TOTAL_DISTANCE ASC;  

这给出了预期的结果,尽管我想知道是否还有更简单的解决方案...

P_FROM, P_TO, FULL_ROUTE, TOTAL_DISTANCE_EXPR, TOTAL_DISTANCE
A         E     A->B->E     +4+22              26
A         E     A->C->E     +7+29              36
A         E     A->B->C->E  +4+10+29           43
相关问题