基于上一行和下一行的 Postgres 查询

Roy*_*nto 6 sql postgresql dijkstra pgrouting

我正在尝试解决 postgresql 中的总线路由问题,该问题需要前一行和下一行的可见性。这是我的解决方案。

步骤1)有一个代表所有边的边表(源和目标代表顶点(公交车站):

postgres=# select id, source, target, cost from busedges;
 id | source | target | cost
----+--------+--------+------
  1 |      1 |      2 |    1
  2 |      2 |      3 |    1
  3 |      3 |      4 |    1
  4 |      4 |      5 |    1
  5 |      1 |      7 |    1
  6 |      7 |      8 |    1
  7 |      1 |      6 |    1
  8 |      6 |      8 |    1
  9 |      9 |     10 |    1
 10 |     10 |     11 |    1
 11 |     11 |     12 |    1
 12 |     12 |     13 |    1
 13 |      9 |     15 |    1
 14 |     15 |     16 |    1
 15 |      9 |     14 |    1
 16 |     14 |     16 |    1
Run Code Online (Sandbox Code Playgroud)

步骤 2) 建立一个表格,其中表示总线详细信息,例如从时间、到时间、边沿等。

注意:我对“from”和“to”列使用了整数格式,以获得更快的结果,因为我可以执行整数查询,但如果可用,我可以用任何更好的格式替换它。

postgres=# select id, "busedgeId", "busId", "from", "to" from busedgetimes;
 id | busedgeId | busId | from  |  to
----+-----------+-------+-------+-------
 18 |         1 |     1 | 33000 | 33300
 19 |         2 |     1 | 33300 | 33600
 20 |         3 |     2 | 33900 | 34200
 21 |         4 |     2 | 34200 | 34800
 22 |         1 |     3 | 36000 | 36300
 23 |         2 |     3 | 36600 | 37200
 24 |         3 |     4 | 38400 | 38700
 25 |         4 |     4 | 38700 | 39540
Run Code Online (Sandbox Code Playgroud)

步骤3)使用dijkstra算法寻找最近路径。

步骤4)从busedgetimes表中按照最早的第一顺序获取通过dijkstra算法检测到的最近路径的即将到来的公交车。

问题:我发现很难进行第 4 步的查询。

例如:如果我得到的路径为边 2、3、4,则从上述记录中的源顶点 2 到目标顶点 5。要获得第一个边缘的第一条总线,这并不难,因为我可以简单地查询,from < 'expected departure' order by from desc但对于第二个边缘,from条件需要to第一个结果行的时间。此外,查询需要边缘 ID 过滤器。

如何在单个查询中实现此目的?

S-M*_*Man 8

我不确定我是否正确理解了你的问题。但是从其他行获取值可以通过窗口函数来完成(https://www.postgresql.org/docs/current/static/tutorial-window.html):

演示:db<>fiddle

SELECT
    id,
    lag("to") OVER (ORDER BY id) as prev_to,
    "from",
    "to",
    lead("from") OVER (ORDER BY id) as next_from
FROM bustimes;
Run Code Online (Sandbox Code Playgroud)

lag函数将前一行的值移至当前行。该lead函数对下一行执行相同的操作。因此,您可以计算上次到达和当前出发之间的差异或类似的东西。

结果

id   prev_to   from    to      next_from
18             33000   33300   33300
19   33300     33300   33600   33900
20   33600     33900   34200   34200
21   34200     34200   34800   36000
22   34800     36000   36300        
Run Code Online (Sandbox Code Playgroud)

请注意,“from”和“to”是 PostgreSQL 中的保留字。最好选择其他名称。