#sql #postgresql #recursive-query
#sql #postgresql #рекурсивный запрос
Вопрос:
У меня есть таблица trainschedule
, которая выглядит следующим образом:-
train_id | source | destination | distance | departure_time | arrival_time
---------- --------- ------------- ---------- ---------------- --------------
22435 | Kolkata | Bhopal | 1200 | 08:00:00 | 17:00:00
21484 | Mumbai | Jaipur | 500 | 13:23:44 | 13:23:45
21424 | Delhi | Mumbai | 800 | 13:23:44 | 15:05:40
12456 | Bhopal | Mumbai | 800 | 11:00:00 | 23:00:00
12453 | Banaras | Mumbai | 500 | 11:00:00 | 21:00:00
21514 | Jaipur | Madras | 1500 | 10:05:00 | 13:23:45
21414 | Delhi | Kolkata | 800 | 14:05:00 | 15:05:40
23432 | Bhopal | Hyderabad | 670 | 12:00:00 | 20:20:00
(8 rows)
Учитывая исходный город, например Дели, и город назначения, например Мумбаи, я должен вернуть количество путей между этими двумя городами.
Я не знаю, как я могу это найти, все, что я смог придумать, это:-
with recursive path(f,t) as(
select source,destination
from trainschedule
union
select trainschedule.source,path.t
from trainschedule,path
where trainschedule.destination=path.f)
select t
from path;
и это дает мне все города, до которых можно добраться из данного города. Я не знаю, что теперь делать. Буду признателен за любую помощь. Спасибо!
Комментарии:
1. Что произойдет, если между двумя городами окажется более двух возможных маршрутов? Как об этом сообщается?
2. @TimBiegeleisen Это какая-то проблема или подсказка?
3. Почему бы просто не посчитать (*) group по t?
4. @Факт, это было неверно…
5. У вас есть пример вывода
Ответ №1:
Вы выполнили всю тяжелую работу в рекурсивном cte. Вам нужно внести только одно изменение, которое заключается в использовании UNION ALL
вместо UNION
, чтобы вы получили строку для каждого пути из одного города в другой. Затем вы можете просто выбрать каждую пару городов и подсчитать количество строк для этой пары в cte:
with recursive path(f,t) as(
select source,destination
from trainschedule
union all
select trainschedule.source,path.t
from trainschedule,path
where trainschedule.destination=path.f)
select f, t, count(*)
from path
group by f, t
order by f, t;
Вывод (для вашего примера данных):
f t count
Banaras Jaipur 1
Banaras Madras 1
Banaras Mumbai 1
Bhopal Hyderabad 1
Bhopal Jaipur 1
Bhopal Madras 1
Bhopal Mumbai 1
Delhi Bhopal 1
Delhi Hyderabad 1
Delhi Jaipur 2
Delhi Kolkata 1
Delhi Madras 2
Delhi Mumbai 2
Jaipur Madras 1
Kolkata Bhopal 1
Kolkata Hyderabad 1
Kolkata Jaipur 1
Kolkata Madras 1
Kolkata Mumbai 1
Mumbai Jaipur 1
Mumbai Madras 1