Запрос Postgres, основанный на предыдущих и следующих строках
Не уверен, что мой дизайн достаточно хорош, чтобы со временем решить проблему маршрутизации автобусов. Вот мое решение с основными шагами, приведенными ниже:
Шаг 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) Иметь таблицу, которая представляет детали шины, такие как время от времени, край и т. Д.
ПРИМЕЧАНИЕ. Я использовал целочисленный формат для столбцов "от" и "до" для более быстрых результатов, поскольку я могу выполнять целочисленный запрос, но я могу заменить его на любой лучший формат, если он доступен.
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) Используйте алгоритм Дейкстры, чтобы найти ближайший путь.
Шаг 4) Получить предстоящие шины из таблицы busedgetimes в самом раннем первом порядке для ближайшего пути, обнаруженного алгоритмом dijkstra.
Проблема: мне трудно сделать запрос для шага 4.
Например: если я получу путь как ребра 2, 3, 4, чтобы перейти от исходной вершины 2 к целевой вершине 5 в приведенных выше записях. Чтобы получить первую шину для первого края, это не так сложно, как я могу просто запросить с from < 'expected departure' order by from desc
но для второго края, from
условие требует to
время первого результата строки. Кроме того, для запроса требуется фильтр идентификаторов ребер.
Как я могу добиться этого в одном запросе? Кроме того, пожалуйста, предложите мне, если есть какие-либо лучшие проекты для этого?
Спасибо
1 ответ
Я не уверен, правильно ли я понял вашу проблему. Но для получения значений из других строк это можно сделать с помощью оконных функций ( 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
Обратите внимание, что "от" и "до" являются зарезервированными словами в PostgreSQL. Было бы лучше выбрать другие имена.