2017-02-02 117 views
4

我在postgres中的表如下所示。将数组中的值解释为有向图中连接的节点的ID。我想是可能的路径列表(每行的最后一个ID与其他行的第一个ID匹配)PostgreSQL聚合节点递归

数据:

foo 
------- 
{1} 
{2,7} 
{3,4} 
{4,6} 
{5} 
{6,8} 
{7} 
{8} 

预期结果:

{1} 
{2,7} 
{3,4,6,8} 
{5} 

我尝试使用递归查询和窗口函数,但它不工作,因为我的预期。

+0

所以他们加入只有对最后INT流入排满足? –

+0

是的,确切地说,我们将每行的最后一个int与其他行中的第一个int进行匹配 – pastDexter

回答

2

你寻找的是这样的:

WITH RECURSIVE x AS (
     -- choose first level - without more connections 
     SELECT id, id AS full_id, 1 AS level 
      FROM foo 
     WHERE NOT EXISTS (
       SELECT 1 
       FROM foo AS foo2 
       WHERE foo.id != foo2.id 
        AND foo.id[1] = foo2.id[array_length(foo2.id, 1)]) 
     -- add tail 
     UNION ALL 
     SELECT x.id, x.full_id || foo.id[2:array_length(foo.id, 1)], level + 1 
      FROM x 
      JOIN foo ON (
       foo.id != x.id 
       AND foo.id[1] = x.full_id[array_length(x.full_id, 1)] 
       AND array_length(foo.id, 1) != 1) 
), z AS ( 
    -- looks for maximum length 
    SELECT max(level) OVER (PARTITION BY id), * FROM x 
) 
-- choose only with maximum length 
SELECT full_id FROM z WHERE max = level