Consider that I have a table of points, each point has 2 coordinates. For example:
Source | Destination
1 | 2
2 |
with recursive
points(src, dst) as (values(1,2),(3,7),(2,3),(5,7),(9,12)),
result as (
select src, dst, array[src,dst] as point, 1 as n
from points p1
where not exists(select * from points p2 where p2.dst = p1.src)
union all
select result.src, points.dst, array[points.src, points.dst], n+1
from result join points on (result.dst = points.src)
)
select array_agg(point order by n) from result group by src;
Use a recursive cte with an array[array[source, destination]]
as an aggregation column:
with recursive cte(source, destination, path) as (
select source, destination, array[array[source, destination]]
from points
union all
select p.source, p.destination, path || array[p.source, p.destination]
from cte c
join points p on c.destination = p.source
where not array[array[p.source, p.destination]] <@ path
)
select distinct on (path[1:1]) path
from (
select distinct on (source, destination) *
from cte
order by source, destination, array_length(path, 1) desc
) s
order by path[1:1], array_length(path, 1) desc;
path
---------------------
{{1,2},{2,3},{3,7}}
{{5,7}}
{{9,12}}
(3 rows)