我在PostgreSQL中遇到了一个关于ltree数据类型列的问题,如下所示.

这是Asset人表:

Id Name GroupId
1 Ass1 1
2 Ass2 1
3 Ass3 2
4 Ass4 3
5 Ass5 4
6 Ass6 4
7 Ass7 4

这是AssetGroup人表:

Id Name Path Level
1 grp1 1 1
2 grp2 1.2 2
3 grp3 3 1
4 grp4 3.4 2

我想创建一个查询语句来计算每个组拥有的assets资源 数量,并期望父组的assets资源 数量的结果是它自己及其子记录拥有的assets资源 总数.

预期结果应该是:

Id Name Path Level AssetQuantity
1 grp1 1 1 3
2 grp2 1.2 2 1
3 grp3 3 1 4
4 grp4 3.4 2 3

我的维护查询是:

SELECT grp_parent."Id"
    , grp_parent."Name"
    , grp_parent."Path"
    , grp_parent."Level"
    , COUNT("Asset".*) AS "AssetQuantity"
FROM "AssetGroup" grp_parent
LEFT JOIN "AssetGroup" grp_child
ON (
    grp_parent."Path" @> grp_Child."Path"
    AND grp_child."DelFlag" = FALSE
)
JOIN "Asset" ON (
    grp_child."Id" = "Asset"."GroupId"
    AND "Asset"."DelFlag" = FALSE
)
GROUP BY grp_parent."Path"
, grp_parent."Id"

然而,目前的结果是:

Id Name Path Level Quantity
1 grp1 1 1 3
2 grp2 1.2 2 1

有没有人能帮我一下?

推荐答案

使用递归cte:

with recursive cte as (
   select g.id, g.name, g.path, g.level, g.level level1, g.id id1, g.path p1 
   from assetgroup g
   union all
   select c.id, c.name, c.path, c.level, g1.level level1, g1.id id1, g1.path p1 from cte c 
   join assetgroup g1 on g1.path ~ ('^'||c.path) 
   where c.level1 < g1.level
)
select c.id, c.name, c.path, c.level, sum(case when a.groupid is null then 0 else 1 end) c from cte c 
left join asset a on a.groupid = c.id1
group by c.id, c.name, c.path, c.level
order by c.id

See fiddle

Sql相关问答推荐

提取Snowflake SQL中的嵌套键

如何在VB.NET中使用MS SYS根据开始和结束期间日期进行查询

如何重用表值用户定义函数调用的结果?

按日期时间(不包括秒)连接表

Select 非重复值并按条件排除行

从结果SQL查询中排除空值

无法访问级联删除导致的触发器中已删除的外键记录

从重复值中获取最新值

仅当 SQL Server 中的表为开时,才在存储过程中使用更改跟踪

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

如何查询自引用 comments 表以查找带有回复的 comments ,并按最新回复排序?

计算 BigQuery 中列的中值差 - 分析函数不能作为聚合函数的参数

在没有订单的情况下,如何生成一个值为0的顾客天数行

BigQuery数组是否包含NULL值的判断方法

标量子查询中的窗口函数不起作用

IN子句使用的表值用户定义函数参数

Select 字段,除非另一个字段包含重复项

运算符不存在:integer = bigint[]

创建一个将层次 struct 级别放入列中的查询

SQL中所有先前日期的累计总和