Get the paths from a database of points in sql

不打扰是莪最后的温柔 提交于 2019-12-31 03:54:14

问题


Consider that I have a table of points, each point has 2 coordinates. For example:

Source       |       Destination 
1            |       2
2            |       3
3            |       7
5            |       7
9            |       12

I'd like to write a query in SQL that gives me the following:

  1. All the paths that these points make. Each path must have connected points, as in the next point's source coordinate is the same as the previous point's destination point.
  2. a path can't be cyclic.

For example, in the table above, running the query should return 3*paths:

  1. (1,2) (2,3) (3,7)
  2. (5,7)
  3. (9,12)

I thought about duplicating the points table, let's call them A and B, then set a condition:

SELECT source, destination 
FROM A, B
WHERE A.source = B.destination

But I'm not sure about the answer and I'm almost sure it's not optimal.


回答1:


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)



回答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;


来源:https://stackoverflow.com/questions/44140864/get-the-paths-from-a-database-of-points-in-sql

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!