【问题标题】:Find connected edges in the graph在图中查找连接边
【发布时间】:2019-10-16 19:07:38
【问题描述】:

我有一个有两列的表。此表中的每一行都是图中的边:

v  |  w
-------
a     a
a     b
a     c
b     d
b     b
c     c
e     f
g     e
h     h

我需要收集所有连接在一起的边:

result 
-------
a,b,c,d
e,f,g
h

最好的方法是什么?创建一个游标并在表上循环并将所有边收集到临时表?或者可能有一些功能可以让这个任务更方便?

更新

create table tt (
    v text,
    w text    
);

insert into tt values('a', 'a');
insert into tt values('a', 'b');
insert into tt values('a', 'c');
insert into tt values('d', 'd');
insert into tt values('b', 'b');
insert into tt values('c', 'c');
insert into tt values('e', 'f');
insert into tt values('g', 'e') ;
insert into tt values('h', 'h') ;

【问题讨论】:

  • 边的起点是什么? v = w?
  • @a_horse_with_no_name 没有起点。它是无向图。

标签: postgresql


【解决方案1】:

最好的办法是在这里使用递归 CTE:

WITH RECURSIVE reccte AS
(
        SELECT v as parent, w as child
        FROM mytable
        UNION ALL
        SELECT reccte.parent, mytable.w
        FROM reccte INNER JOIN mytable ON reccte.child = mytable.v and mytable.v <> mytable.w
)
SELECT STRING_AGG(DISTINCT child, ',')
FROM (SELECT parent, child FROM reccte UNION SELECT parent, parent FROM reccte) r1
WHERE parent NOT IN (SELECT child FROM reccte r2 WHERE r2.parent <> r1.parent)
GROUP BY parent

会吐出来的:

string_agg 
------------
 a,b,c,d
 e,f,g
 h

递归 CTE 分为两部分。 UNION 之前的最高位是递归的起点。我们只是抓取所有记录。 UNION 之后的第二位是递归部分,它引用自身。基本上,它将节点链接到节点(父节点到子节点)并添加到结果集中,直到它耗尽自己的记录。

最后是递归 CTE 中的 SELECT,我们使用该联合获取所有组合,然后删除 parent 是另一个 parents children 的任何记录。然后,我们只需将STRING_AGG() 提高到每个parentchildren 并吐出结果。

【讨论】:

  • 我已经理解了这个想法,但是这个查询正在运行无限时间)
  • 它有可能无限循环。是否存在循环的关系,例如 a,b,c,a,b,c,a,b,c...?可能必须添加到第二个 WHERE 子句以避免循环。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多