我有 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 项目的一部分,如果这有影响的话。
听起来您正在寻找
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