我使用的是Postgres 9.4,我有3个表:truck
,container
和container_metadata
。
truck
可以包含多个container
和container
多个container_metadata
。
我稍后会在下表中添加更多说明(我尽力创建它们),所以这里有:
卡车可以包含许多由钥匙 truck_id
引用的集装箱
容器然后由 我试图解决的问题是创建一个视图,以便于查询和模型创建(用于数据库)。我将在下面添加更多详细信息。 在最后一栏中, 更多详情: 我只能计算容器,子容器,我一直在尝试集合功能,但我对这个问题不熟悉,我希望这些表有所帮助。请问是否需要更多说明。 到目前为止我的尝试: 假设架构是公开的。以上是我尝试的查询,但它输出的子容器数量错误,而且我已经走了多远。container_metadata
表描述,容器也可以有许多不同类型的记录,但在这种情况下,我将只关注“all good
如果卡车有:{/ p>,则为真
subcontainer
的记录。
查询
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
;
答案 0 :(得分:1)
假设container_metadata.volume
为NOT 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;
主要功能是首先聚合,然后加入到下一个上一级。不仅在处理大部分或全部表格时它通常更快,它还允许一举聚合每个级别:
您需要非常小心NULL
值可以进入的位置。这些值可以通过列值或LEFT JOIN
(缺少的行)引入。因此,必须观察哪些列可以为NULL。该查询仅与拟合表定义一起有效。
当然,您需要了解logical和comparison operators,特别是涉及NULL值。
汇总FILTER
需要Postgres 9.4:
SQL Fiddle没有数据,因为没有提供数据。所以没有经过测试。