代码之家  ›  专栏  ›  技术社区  ›  Royal Pinto

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

  •  2
  • Royal Pinto  · 技术社区  · 6 年前

    我不确定我的设计是否足够好来解决随时间推移的公交路线问题。以下是我的解决方案,主要步骤如下:

    步骤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
    

    步骤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
    

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

    步骤4)根据dijkstra算法检测到的最近路径,从busedgetimes表中以最早的一阶获得即将到来的总线。

    问题:我发现很难对步骤4进行查询。

    from < 'expected departure' order by from desc 但对于第二个边缘 from 条件要求 to 第一个结果行的时间。此外,查询需要边缘ID过滤器。

    如何在单个查询中实现这一点?另外,请建议我,如果有任何更好的设计这个?

    谢谢

    1 回复  |  直到 6 年前
        1
  •  3
  •   S-Man    6 年前

    窗口函数 ( https://www.postgresql.org/docs/current/static/tutorial-window.html

    demo: 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;
    

    这个 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        
    

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