基于上一行和下一行的 Postgres 查询
Postgres Query Based on Previous and Next Rows
不确定我的设计是否足以随着时间的推移解决总线路由问题。这是我的解决方案,主要步骤如下:
Step 1) 有一条边table代表所有的边(源和目标代表顶点(公交车站):
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 步)有一个 table 表示总线详细信息,例如从时间、到时间、边缘等。
NOTE: I have used integer format for "from" and "to" column for faster results as I can do an integer query, but I can replace it with any better format if available.
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算法寻找最近的路径。
Step 4) 从 busedgetimes table 中获取 dijkstra 算法检测到的最近路径中最早的第一个顺序即将到来的公交车。
问题:我发现很难进行第 4 步的查询。
例如:如果我在上述记录中得到的路径为边2、3、4,从源顶点2行进到目标顶点5。要获得第一条边的第一条总线,并不像我可以简单地使用 from < 'expected departure' order by from desc
查询那么难,但是对于第二条边,from
条件需要第一个结果行的 to
时间。此外,查询需要边 ID 过滤器。
如何在单个查询中实现这一点?另外请问有什么更好的设计吗?
谢谢
我不确定我是否正确理解了你的问题。但是从其他行获取值可以通过 window functions (https://www.postgresql.org/docs/current/static/tutorial-window.html):
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 中的保留字。最好选择其他名称。
不确定我的设计是否足以随着时间的推移解决总线路由问题。这是我的解决方案,主要步骤如下:
Step 1) 有一条边table代表所有的边(源和目标代表顶点(公交车站):
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 步)有一个 table 表示总线详细信息,例如从时间、到时间、边缘等。
NOTE: I have used integer format for "from" and "to" column for faster results as I can do an integer query, but I can replace it with any better format if available.
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算法寻找最近的路径。
Step 4) 从 busedgetimes table 中获取 dijkstra 算法检测到的最近路径中最早的第一个顺序即将到来的公交车。
问题:我发现很难进行第 4 步的查询。
例如:如果我在上述记录中得到的路径为边2、3、4,从源顶点2行进到目标顶点5。要获得第一条边的第一条总线,并不像我可以简单地使用 from < 'expected departure' order by from desc
查询那么难,但是对于第二条边,from
条件需要第一个结果行的 to
时间。此外,查询需要边 ID 过滤器。
如何在单个查询中实现这一点?另外请问有什么更好的设计吗?
谢谢
我不确定我是否正确理解了你的问题。但是从其他行获取值可以通过 window functions (https://www.postgresql.org/docs/current/static/tutorial-window.html):
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 中的保留字。最好选择其他名称。