Oracle 层次结构查询

Oracle hierarchy queries

我有下一个 table,我需要编写层次结构查询:

1.What 两步即可到达的城市

2.Find两个城市之间的最低路线。

+-------------+-------------+----------+
|    City1    |    City2    | Distance |
+-------------+-------------+----------+
| Leningrad   | Vladivostok |      234 |
| Vladivostok | Viborg      |      423 |
| Viborg      | Novgograd   |       92 |
| Novgograd   | Tula        |      158 |
| Leningrad   | Tula        |      321 |
| Tula        | Moscow      |      111 |
| Moscow      | Novgograd   |      421 |
| Leningrad   | Moscow      |      244 |
+-------------+-------------+----------+

我遇到了类似的问题

WITH stepbystep ( city1, city2, distance ) AS (
  SELECT city1, city2 || '-' || city1, distance
  FROM   route
  WHERE  city1 = 'Moscow'
     UNION ALL
  SELECT r.city1
       , s.city2 || '-' || r.city1
       , r.distance + s.distance
  FROM route r
       INNER JOIN
       stepbystep s
       ON ( s.city1 = r.city2 )
  )
SELECT city2, distance FROM stepbystep

要分两步获取城市,您可以尝试以下查询 -

stepbystep ( city1, city2, distance, lvl ) AS (
  SELECT city1, city1 || '-' || city2, distance, 1 lvl
  FROM   route
  --WHERE  city1 = 'Moscow'
     UNION ALL
  SELECT r.city1
       , r.city1 || '-' || s.city2
       , r.distance + s.distance
       , s.lvl+1
  FROM route r
       INNER JOIN
       stepbystep s
       ON ( s.city1 = r.city2 )
  WHERE s.lvl <= 2
  )
SELECT city2, distance FROM stepbystep
WHERE lvl = 2              -- Using lvl =2 to get the cities in 2 steps.

Here 就是 fiddle.

对于最短路径,您可以尝试以下查询 -

stepbystep ( city1, city2, distance, lvl ) AS (
  SELECT city1, city1 || '-' || city2, distance, 1 lvl
  FROM   route
  --WHERE  city1 = 'Moscow'
     UNION ALL
  SELECT r.city1
       , r.city1 || '-' || s.city2
       , r.distance + s.distance
       , s.lvl+1
  FROM route r
       INNER JOIN
       stepbystep s
       ON ( s.city1 = r.city2 )
  WHERE s.lvl <= 2
  )
select city1
      ,substr(city2, instr(city2, '-', -1)++1, length(city2)) dest
      ,distance
from (select city2
            ,city1
            ,substr(city2, instr(city2, '-', -1)++1, length(city2)) dest
            ,distance
            ,rank() over(partition by city1, substr(city2, instr(city2, '-', -1)++1, length(city2)) order by distance) rnk
      from stepbystep)
where rnk = 1

Here 是演示。