Запрос Postgres, основанный на предыдущих и следующих строках - PullRequest
0 голосов
/ 27 сентября 2018

Не уверен, что мой дизайн достаточно хорош, чтобы решить проблему маршрутизации шины со временем.Вот мое решение с основными шагами, приведенными ниже:

Шаг 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) Используйте алгоритм dijkstra, чтобы найти ближайший путь.

Шаг 4) Получить предстоящие шины из таблицы busedgetimes в самом раннем первом порядке для ближайшего пути, обнаруженного алгоритмом dijkstra.

Проблема: мне трудно выполнить запрос для шага 4.

Например: если я получу путь в виде ребер 2, 3, 4, чтобы перейти от исходной вершины 2 к целевой вершине 5 в приведенных выше записях.Чтобы получить первую шину для первого ребра, это не так сложно, как я могу просто запросить с помощью from < 'expected departure' order by from desc, но для второго ребра условие from требует to времени первой строки результатов.Кроме того, для запроса требуется фильтр идентификаторов ребер.

Как этого добиться в одном запросе?Кроме того, пожалуйста, предложите мне, если есть какие-либо лучшие проекты для этого?

Спасибо

1 Ответ

0 голосов
/ 27 сентября 2018

Я не уверен, правильно ли я понял вашу проблему.Но для получения значений из других строк это можно сделать с помощью оконных функций (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. Было бы лучше выбрать другие имена.

...