【问题标题】:Oracle hierarchy queriesOracle 层次结构查询
【发布时间】:2020-04-17 17:37:34
【问题描述】:

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

1.2步可以到达哪个城市。

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

+-------------+-------------+----------+
|    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

【问题讨论】:

  • 1) 分层查询在两个步骤中结束。请改用自联接。 (除非需要推广到更多步骤。) 2)请注意,在某些情况下,连接条件是 City1 到 City2,但其他情况下是 City1 到 City1 或 City2 到 City2。例如,莫斯科通过诺夫哥格勒到维堡是两个步骤,但诺夫哥格勒在两行都是City2。

标签: sql oracle hierarchy


【解决方案1】:

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

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 是小提琴。

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

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 是演示。

【讨论】:

    猜你喜欢
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多