Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

334
Visualizações
How to get array of descendants from adjacency lists?

I have the following table and data

CREATE TABLE relationships (a TEXT, b TEXT);
CREATE TABLE nodes(n TEXT);
INSERT INTO relationships(a, b) VALUES 
 ('1', '2'), 
 ('1', '3'),
 ('1', '4'),
 ('1', '5'),
 ('2', '6'),
 ('2', '7'),
 ('2', '8'),
 ('3', '9');
INSERT INTO nodes(n) VALUES ('1'), ('2'), ('3'), ('4'), ('5'), ('6'), ('7'), ('8'), ('9'), ('10');

I want to output

  n  |  children
  1  |  ['2', '3', '4', '5', '6', '7', '8', '9']
  2  |  ['6', '7', '8', '9']
  3  |  ['9']
  4  |  []
  5  |  []
  6  |  []
  7  |  []
  8  |  []
  9  |  []
  10 |  []

I am trying to use WITH RECURSIVE but is stuck on how to pass parameter into CTE

WITH RECURSIVE traverse(n) AS (
    SELECT *
    FROM relationships
    WHERE a = n --- not sure how to pass data to here
    UNION ALL
    ...
)
WITH basic_cte AS (
    SELECT a1.n as n,
           (SELECT COALESCE(json_agg(temp), '[]')
            FROM (
                         (SELECT * FROM traverse(a1.a))
                 ) as temp
           ) as children
    FROM nodes as a1
)
SELECT *
FROM basic_cte;
over 4 years ago · Santiago Trujillo
2 Respostas
Responde à pergunta

0

Note: This ignores any empty children. You can add a left join like in @a_horse_with_no_name's answer to get that functionality.

You can't really pass a parameter into the CTE unless you veer off into stored procedures and whatnot. The CTE is a single table that needs to contain all the rows you might want to use from it.

Assuming a fairly nice graph (no duplicate edges, no cycles), code like the following ought to do what you're looking for.

  • The base case for the recursive query gets all level-1 descendants (the children) for all nodes which could possibly be parents.
  • The recursive step walks through the 2nd level, 3rd level, etc down the tree.
  • Once we have all parent-descendant tuples we can aggregate the data as desired.
WITH RECURSIVE descendants(parent, child) AS (
    SELECT * FROM relationships
    UNION
    SELECT d.parent, r.b
    FROM descendants d JOIN relationships r ON d.child=r.a
)
SELECT parent AS n, array_agg(child) AS children
FROM descendants
GROUP BY parent
over 4 years ago · Santiago Trujillo Relatório

0

To get a list of the children of all nodes, you need a left join to the nodes table

with recursive rels as (
  select a,b, a as root
  from relationships
  union all
  select c.*, r.root
  from relationships c
    join rels r on r.b = c.a
)
select n.n, array_agg(r.b) filter (where r.b is not null)
from nodes n
  left join rels r on r.root = n.n
group by n.n
order by n.n;
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda