PostgreSQL WHERE 位于 INNER JOIN 表上,但包含右表上匹配的所有行

问题描述 投票:0回答:1

我有 2 个具有一对多关系的表。表 A 包含“对象”,表 B 包含“组件”,它们具有相关的 id,我编写了一个查询来收集表 A 中的所有对象以及表 B 中的关联组件,如下所示:

SELECT A.*, ARRAY_AGG(B.*) FROM A INNER JOIN B USING(id) GROUP BY A.*

这满足了我的期望。

接下来我在 B 上有一个名为“type”的字段,可以是“X”、“Y”或“Z”。我想做与上面相同的查询,但过滤结果,以便仅包含具有关联组件(其中 B.type = 'X')的对象。此外,我仍然想要每个返回的对象的所有不是 B.type = 'X' 的关联组件。

我的第一次尝试是编写以下查询:

SELECT A.*, ARRAY_AGG(B.*) FROM A INNER JOIN B USING(id) WHERE B.type = 'X' GROUP BY A.*

但是此查询会删除类型不是 = 'X' 的组件。

有没有办法获取所有具有 type = 'X' 关联组件的对象,并且结果集返回每个对象的所有关联组件(无论类型如何)?

这是一个包含预期结果集的示例数据集:

答:

id
1
2
3
4

乙:

id 类型
1 X
1
1 Z
2
2 Z
3 X
4 Z
Result:
(1, [(1,X),(1,Y),(1,Z)]),
(3, [(3,X)])

这些查询是 SQLX Rust 项目的一部分,如果这有影响的话。

postgresql sqlx
1个回答
0
投票

听起来您正在寻找

HAVING
子句。

SELECT A.*
     , ARRAY_AGG(B.*)F
FROM A JOIN B USING(id) 
GROUP BY A.*
HAVING 'X'=ANY(ARRAY_AGG(B.type));--easy, readable
--HAVING bool_or(B.type='X');--efficient
© www.soinside.com 2019 - 2024. All rights reserved.