递归查询以生成路径的边缘?

Recursive query to produce edges of a path?

我有一个 table paths:

CREATE TABLE paths (
    id_travel INT,
    point INT,
    visited INT
);

示例行:

 id_travel | point | visited 
-----------+-------+---------
        10 |   35  |       0
        10 |   16  |       1
        10 |   93  |       2
         5 |   15  |       0
         5 |   26  |       1
         5 |  193  |       2
         5 |   31  |       3

还有一个table distances:

CREATE TABLE distances (
    id_port1 INT,
    id_port2 INT,
    distance INT CHECK (distance > 0),
    PRIMARY KEY (id_port1, id_port2)
);

我要发表意见:

 id_travel | point1 | point2 | distance 
-----------+--------+--------+---------
        10 |   35   |     16 |  1568
        10 |   16   |     93 |  987
         5 |   15   |     26 |  251
         5 |   26   |    193 |  87
         5 |  193   |     31 |  356

我不知道如何通过这里的递归请求dist_trips:

CREATE VIEW dist_view AS
WITH RECURSIVE dist_trips (id_travel, point1, point2) AS 
   (SELECT ????)
SELECT dt.id_travel, dt.point1, dt.point2, d.distance
FROM dist_trips dt
NATURAL JOIN distances d;

dist_trips 是递归请求 并且应该 return 三列:id_travelpoint1point2 来自 table paths.

你不需要递归。可以是普通连接:

SELECT id_travel, p1.point AS point1, p2.point AS point2, d.distance 
FROM   paths p1
JOIN   paths p2 USING (id_travel)
LEFT   JOIN distances d ON d.id_port1 = p1.point
                       AND d.id_port2 = p2.point
WHERE  p2.visited = p1.visited + 1
ORDER  BY id_travel, p1.visited;

db<>fiddle here

你的路径似乎有无间隙的升序数字。只需将每个点与下一个连接起来即可。

我加入了一个 LEFT JOIN 以在结果中保留每条路径的所有边缘,即使 distances table 不应该有匹配的条目。可能是谨慎的。

你的 NATURAL JOIN 哪儿也没去。通常,NATURAL 很少有用,而且很容易损坏。 The manual warns:

USING is reasonably safe from column changes in the joined relations since only the listed columns are combined. NATURAL is considerably more risky since any schema changes to either relation that cause a new matching column name to be present will cause the join to combine that new column as well.