从sql中的点数据库获取路径

从sql中的点数据库获取路径,sql,postgresql,recursive-query,Sql,Postgresql,Recursive Query,假设我有一个点表,每个点有2个坐标。例如: Source | Destination 1 | 2 2 | 3 3 | 7 5 | 7 9 | 12 我想用SQL编写一个查询,提供以下信息: 这些点形成的所有路径。每个路径必须具有连接点,因为下一点的源坐标与上一点的目标点相同。 路径不能是循环的。 例如

假设我有一个点表,每个点有2个坐标。例如:

Source       |       Destination 
1            |       2
2            |       3
3            |       7
5            |       7
9            |       12
我想用SQL编写一个查询,提供以下信息:

这些点形成的所有路径。每个路径必须具有连接点,因为下一点的源坐标与上一点的目标点相同。 路径不能是循环的。 例如,在上表中,运行查询应返回3*个路径:

1,2 2,3 3,7 5,7 9,12 我考虑复制点表,让我们称它们为A和B,然后设置一个条件:

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

但我不确定答案,而且我几乎可以肯定它不是最优的。

使用递归cte和数组[array[source,destination]]作为聚合列:

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)

将递归cte与数组[array[source,destination]]一起用作聚合列:

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)

我删除了不兼容的数据库标记。请仅使用您真正使用的数据库进行标记。到目前为止,您所拥有的是正确的。似乎您正在寻找递归。如果postgresql可以使用递归cteI认为路径1,22,33,7应该在结果集中?@klin是的,应该是,我会编辑这篇文章。谢谢。我删除了不兼容的数据库标签。请仅使用您真正使用的数据库进行标记。到目前为止,您所拥有的是正确的。似乎您正在寻找递归。如果postgresql可以使用递归cteI认为路径1,22,33,7应该在结果集中?@klin是的,应该是,我会编辑这篇文章。谢谢。既然你可以用滞后,为什么还要用递归cte?我不这么认为。试着在数据上使用滞后:1,5,2,3,3,4,5,6。如果可以使用滞后,为什么要使用递归cte?我不这么认为。尝试在数据上使用滞后:1,5,2,3,3,4,5,6。