使用来自三层嵌套表的聚合列创建视图

Create view with aggregated columns from three levels of nested tables

我正在使用 Postgres 9.4,我有 3 个 tables:truckcontainercontainer_metadata.
一个 truck 可以有很多 container 而一个 container 可以有很多 container_metadata.

我稍后会在下面的 table 中添加更多描述(我已尽力创建它们),所以这里是:

一辆卡车可以装很多集装箱truck_id

一个容器然后由container_metadata table描述,一个容器也可以有许多不同类型的记录,但在这种情况下,我将只关注'subcontainer'类型。

我要解决的问题是创建一个视图以便于查询和创建模型(用于数据浏览器)。我将在下面添加更多详细信息。

在最后一列中,如果卡车有:

all good 为真

更多详情:

我只能对容器、子容器进行计数我一直在尝试聚合函数,但我是这个问题的新手,希望 table 能有所帮助。请务必询问是否需要更多说明。

查询

我目前的尝试:

select 
t.id,t.name, count(c.id) as container_count, count(cm.id) as subcontainer_count
from
    public.truck t
left join
    public.container c
on
    c.truck_id = t.id
left join
    public.container_metadata cm
on
    cm.container_id = c.id and type = 'subcontainer'
group by t.id
;

假设架构是 public。以上是我试过的查询,但它输出了错误数量的子容器,这就是我得到的结果。

假设 container_metadata.volumeNOT NULL DEFAULT 0,这应该完成全部工作:

SELECT t.id, t.name
     , COALESCE(c.cont_ct, 0)      AS cont_ct
     , COALESCE(c.sub_ct, 0)       AS sub_ct
     , COALESCE(c.empty_ct, 0)     AS empty_ct
     , c.truck_id IS NULL          AS cont_missing
     , c.sub_missing IS NOT FALSE  AS sub_missing
     ,(c.empty_ct = 0) IS NOT TRUE AS sub_needfill
     , c.empty_ct = 0 AND NOT c.sub_missing AS all_good
FROM   truck t
LEFT   JOIN (
   SELECT truck_id
        , count(*) AS cont_ct
        , sum(cm.ct_sub) AS sub_ct
        , sum(cm.ct_empty) AS empty_ct
        , bool_or(cm.container_id IS NULL) AS sub_missing
   FROM   container c
   LEFT JOIN (
      SELECT container_id
           , count(*) AS ct_sub
           , count(*) FILTER (WHERE volume = 0) AS ct_empty
      FROM   container_metadata
      WHERE  type = 'subcontainer'  -- only those seem relevant
      GROUP  BY 1
      ) cm ON cm.container_id = c.id
   GROUP  BY 1
   ) c ON c.truck_id = t.id;

主要特点是先聚合,然后然后加入到下一个上层。无论如何,它不仅在处理大部分或全部 table 时通常更快,而且还允许一次性聚合每个级别:

  • Why does the following join increase the query time significantly?

您需要非常小心 NULL 值可能会悄悄出现的地方。这些值可以通过列值或 LEFT JOIN(缺失行)引入。因此,必须观察哪些列可以为 NULL。该查询仅与拟合 table 定义结合使用才有效。

当然,您需要了解 logical and comparison operators,尤其是涉及 NULL 值时。

聚合 FILTER 需要 Postgres 9.4:

  • How can I simplify this game statistics query?

SQL Fiddle 没有数据,因为没有提供数据。所以也没有测试。