当前位置: 首页 > 面试题库 >

PostgreSQL中的层次求和

颛孙森
2023-03-14
问题内容

这是我在PostgreSQL中遇到的问题的简化版本。

我有下表 A

[ID INTEGER | 数值 NUMERIC(10,2) | 父 整数 ]

其中“ PARENT”是列ID的自引用FK。

该表的定义是:

CREATE TABLE A(ID INTEGER IDENTITY, VALUE NUMERIC(10,2), PARENT INTEGER)                                    
ALTER  TABLE A ADD CONSTRAINT FK FOREIGN KEY (PARENT) REFERENCES A(ID)

这个简单的表允许定义任意深度的树数据结构。现在,我需要编写一个SQL(我不希望不使用服务器端PL-
SQL)来为每个节点报告子树“挂”下的总值。例如,具有下表:

|  ID  | VALUE | PARENT |
-------------------------
|   1  | NULL  | NULL   |
|   2  | 3.50  |    1   |
|   3  | NULL  | NULL   |
|   4  | NULL  |    3   |
|   5  | 1.50  |    4   |
|   6  | 2.20  |    4   |

我应该得到以下结果集:

| ID  |  Total-Value-of-Subtree |
|  1  |                  3.50   |
|  2  |                  3.50   |
|  3  |                  3.70   |
|  4  |                  3.70   |
|  5  |                  1.50   |
|  6  |                  2.20   |

对于simplicitly,你可以假设,只有叶节点有值,非叶节点总是有一个值 NULL
列。有没有办法在SQL中做到这一点,甚至利用PostgreSQL特定的扩展?


问题答案:

在PostgreSQL中,您可以使用递归CTE(公用表表达式)在查询中遍历树。

这是文档中的两个相关链接:

  • 句法
  • 例子

编辑

由于不需要子选择,因此在较大的数据集上运行可能会比Arion的查询好一些。

WITH RECURSIVE children AS (
    -- select leaf nodes
    SELECT id, value, parent
        FROM t
        WHERE value IS NOT NULL
    UNION ALL
    -- propagate values of leaf nodes up, adding rows 
    SELECT t.id, children.value, t.parent
        FROM children JOIN t ON children.parent = t.id
)
SELECT id, sum(value) 
    FROM children 
    GROUP BY id   -- sum up appropriate rows
    ORDER BY id;


 类似资料:
  • 我是JSON/JSONB数据类型的新手,在选择更深层次的JSONB元素时遇到了一些问题。 对此有什么建议吗?

  • 本文向大家介绍AngualrJS中每次$http请求时的一个遮罩层Directive,包括了AngualrJS中每次$http请求时的一个遮罩层Directive的使用技巧和注意事项,需要的朋友参考一下 AngularJS是一款非常强大的前端MVC框架。在AngualrJS中使用$http每次向远程API发送请求,等待响应,这中间有些许的等待过程。如何优雅地处理这个等待过程呢? 如果我们在等待过程

  • 我有这样的层次结构: 因此,用户可以添加他的工作经验。此外,他还可以为特定的项目添加角色。 我想为用户id 1获取项目,但项目之间只有关系 获取用户 获得工作经验 获取角色 获取项目 因此,如果我有更多不同工作经验的角色,我就必须提出20个请求才能得到我的项目。这不是很有效率吗?我必须加载一些不必要的数据。。。 是否可以只创建endpoint:并按用户ID过滤它? 应该如何在API上管理它?对我来

  • 计算机处理的所有数据项最终都是0和1的组合。采用这种组合方式是因为它非常简单,并且能够经济地制造表示两种稳定状态的电子设备(一种状态代表1,另一种状态代表0)。计算机所完成的复杂功能仅仅涉及最基本的对0和1的操作。 0和1可以认为是计算机中的最小数据项,人们称之为“位”(bit)。bit是binary digit(二进制数字)的缩写,一个二进制数字是0和1的两个值之一。计算机电路完成各种简单的位操

  • 层次遍历 给定二叉树的包含虚结点的先序遍历序列信息,按层次顺序给出遍历的结果。 输入格式: 首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据在一行中输入一个字符串(不含空格且长度不超过80),表示二叉树的先序遍历序列(其中@表示虚结点)。 输出格式: 对于每组测试,输出层次遍历的结果。 输入样例: 1 ABD@@EG@@@C@F@@ 输出样例: ABCDEFG 代码长度限制

  • 分层布局是一种抽象布局,不直接使用。但它允许在不同的分层布局中共享节点。请看下列例子: • Cluster -簇实体构成树状图。 • Pack -使用递归圆填充法创建一个分层布局。 • Partition -将节点树递归划分成辐射状或环状。 • Tree -将节点树整齐放置。 • Treemap -使用递归空间划分显示节点树。 虽然不是分层布局,但捆绑布局可以同分层共同使用。 d3.layout.