PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Consulta SQL do PostgreSQL para percorrer um gráfico não direcionado inteiro e retornar todas as arestas encontradas


Cheguei a isso, não deve entrar em loops infinitos com nenhum tipo de dado:
--create temp table edges ("from" text, "to" text);
--insert into edges values ('initial_node', 'a'), ('a', 'b'), ('a', 'c'), ('c', 'd');

with recursive graph(points) as (
  select array(select distinct "to" from edges where "from" = 'initial_node')
  union all
  select g.points || e1.p || e2.p
  from graph g
  left join lateral (
    select array(
      select distinct "to"
      from edges 
      where "from" =any(g.points) and "to" <>all(g.points) and "to" <> 'initial_node') AS p) e1 on (true)
  left join lateral (
    select array(
      select distinct "from"
      from edges 
      where "to" =any(g.points) and "from" <>all(g.points) and "from" <> 'initial_node') AS p) e2 on (true)
  where e1.p <> '{}' OR e2.p <> '{}'
  )
select distinct unnest(points)
from graph
order by 1

As consultas recursivas são muito limitantes em termos do que pode ser selecionado e, como não permitem usar os resultados recursivos dentro de uma subseleção, não se pode usar NOT IN (selecionar * de recursiva onde...). Armazenar resultados em uma matriz, usando LEFT JOIN LATERAL e usando =ANY() e <>ALL() resolveu esse enigma.