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 是演示。
我有下一个 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 是演示。