Подсчет количества путей

#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
  

Демонстрация на dbfiddle