【问题标题】:Sum distance along with SYS_CONNECT_BY_PATH将距离与 SYS_CONNECT_BY_PATH 相加
【发布时间】:2019-09-01 19:50:22
【问题描述】:

参考this关于SO的问题,输入图表是-

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 语法,这个查询可能会更加简化,所以在尝试某种方式时我设法得到了预期的结果,但距离列不正确 -

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 特定语法来获得正确的总距离。

Here 供您参考。

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

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

    使用+ 简单连接表达式total_distance,然后评估使用xmlquery建议here

    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
    

    【讨论】:

    • 没有比这更好的方法了吗?
    • 不确定@AnkitBajpai SYS_CONNECT_BY_PATH 仅支持字符数据,因此您无法执行添加。您对递归子查询分解的选择似乎没问题。
    猜你喜欢
    • 2013-04-05
    • 2018-09-21
    • 2010-10-31
    • 2017-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-22
    相关资源
    最近更新 更多