首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算祖先数组后代数的最佳方法?

计算祖先数组后代数的最佳方法?
EN

Stack Overflow用户
提问于 2018-11-18 01:04:17
回答 2查看 221关注 0票数 0

tree是一个示例表,其中包含PostgreSQL 8.3+中的祖先数组:

代码语言:javascript
复制
----+-----------
 id | ancestors 
----+-----------
  1 | {}
  2 | {1}
  3 | {1,2}
  4 | {1}
  5 | {1,2}
  6 | {1,2}
  7 | {1,4}
  8 | {1}
  9 | {1,2,3}
 10 | {1,2,5}

为了获得后代的每个id计数数,我可以这样做:

代码语言:javascript
复制
SELECT 1 AS id, COUNT(id) AS descendant_count FROM tree WHERE 1 = ANY(ancestors)
  UNION
SELECT 2 AS id, COUNT(id) AS descendant_count FROM tree WHERE 2 = ANY(ancestors)
  UNION
SELECT 3 AS id, COUNT(id) AS descendant_count FROM tree WHERE 3 = ANY(ancestors)
  UNION
SELECT 4 AS id, COUNT(id) AS descendant_count FROM tree WHERE 4 = ANY(ancestors)
  UNION
SELECT 5 AS id, COUNT(id) AS descendant_count FROM tree WHERE 5 = ANY(ancestors)
  UNION
SELECT 6 AS id, COUNT(id) AS descendant_count FROM tree WHERE 6 = ANY(ancestors)
  UNION
SELECT 7 AS id, COUNT(id) AS descendant_count FROM tree WHERE 7 = ANY(ancestors)
  UNION
SELECT 8 AS id, COUNT(id) AS descendant_count FROM tree WHERE 8 = ANY(ancestors)
  UNION
SELECT 9 AS id, COUNT(id) AS descendant_count FROM tree WHERE 9 = ANY(ancestors)
  UNION
SELECT 10 AS id, COUNT(id) AS descendant_count FROM tree WHERE 10 = ANY(ancestors)

并得到如下结果:

代码语言:javascript
复制
----+------------------
 id | descendant_count
----+------------------
  1 | 9
  2 | 5
  3 | 1
  4 | 1
  5 | 1
  6 | 0
  7 | 0
  8 | 0
  9 | 0
 10 | 0

我想应该存在一个更短或更智能的查询语句来获得相同的结果,可以吗?也许喜欢WITH RECURSIVE或者用循环创建函数来生成查询?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-18 10:11:33

你的一组工会实际上只是一个自我连接..。

代码语言:javascript
复制
SELECT
    tree.id,
    COUNT(descendant.id) AS descendant_count
FROM
    tree
LEFT JOIN
    tree   AS descendant
        ON tree.id = ANY(descendant.ancestors)
GROUP BY
    tree.id
票数 1
EN

Stack Overflow用户

发布于 2018-11-18 01:57:27

乍一看,这是递归查询的一个例子,但这个例子更简单:

只是休息、分组和数数:

代码语言:javascript
复制
SELECT id AS ancestor, COALESCE (a1.id, 0) AS descendants_count
FROM   tree
LEFT   JOIN (
   SELECT a.id, count(*) AS descendant_count
   FROM   tree t, unnest(t.ancestors) AS a(id)
   GROUP  BY 1
   ) a1 USING (id)
ORDER  BY 1;

并且,为了包括没有任何后代的祖先,请加入LEFT JOIN

在集合返回函数unnest()中有一个隐式unnest()连接。请参见:

撇开:

如果您最终不得不使用多个UNION子句,那么请考虑使用UNION ALL。请参见:

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53357009

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档