postgresql - 如何从邻接表中获取后代数组?

标签 postgresql

我有下表和数据

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');

我要输出

  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 |  []

我正在尝试使用 WITH RECURSIVE,但在如何将参数传递给 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;

最佳答案

要获取所有节点的子节点列表,您需要对节点表进行左连接

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;

关于postgresql - 如何从邻接表中获取后代数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62549563/

相关文章:

c++ - 尝试使用 OTL 连接到我的 PostgreSQL 服务器

PostgreSQL log_min_messages 不起作用?

SQL注入(inject)预防方法

mysql - SQL:如何为这样的字符串编写过滤器 - '10xx8xx0xx'(x - 任何符号)?

python - 使用 sqlalchemy 创建一个 db.Sequence

django - 更改最终用户的 postgres 密码

postgresql - 找不到符号 : _PQbackendPID with Django project

ruby-on-rails - 通过迁移或psql设置默认hstore列键值对

postgresql - kubernetes pod 可以动态更改自己的标签吗?

postgresql - Postgres 三元组搜索中 AND OR NOT 的语法是什么?