我有一个非常标准的数据库设置,其中包含父子关系。类似于父表、子表和 parent_child_relationship 表,其中父表有很多并且属于许多子表(因此严格来说不是父子表)。
我想做的是,在为我的 API 编写 SQL 时,提取具有特定 ID 的父级,然后还获取关系中所有子级的子级 ID。
我目前只在两个查询中执行此操作 - select * from parents where id = ?
和 select child_id as id from parent_child_relationship where parent_id = ?
。
我很好奇的是:是否有任何特别好的方法可以在一个查询中完成所有这些操作?我在表单中尝试了类似 array_agg 的东西
select parents.*, array_agg(parent_child_relationship.child_id)
from parents join parent_child_relationship
on parents.id = parent_child_relationship.parent_id
where parents.id = ?
group by parents.id, parents.otherfield, parents.yetanotherfield
但这是非常低效的(当我在父级上有一堆这样的关系时),因为你实际上最终需要在那里做一个独特的过滤器,而且再一次:非常慢。我测试的真实世界查询大约需要 5 分钟才能完成。
我正在使用 EXPLAIN 研究不同的版本来自己解决问题,但我认为这种需求可能相当普遍,并且有一种最佳方法可以做到这一点。
我也可以始终只对每个关系进行一个查询。这感觉就像是一个我可以简化一些东西的地方。
最佳答案
你可以试试这个版本:
select p.*,
(select array_agg(pc.child_id)
from parent_child_relationship pcr
where p.id = pcr.parent_id
) as children
from parents p
where p.id = ?;
我不确定为什么您的版本会很慢。 . .除非你缺少索引。两个版本都需要在 parent_child_relationship(parent_id, child_id)
上建立索引。
关于sql - 使用基本项查询从连接表中进行选择的有效技术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44146923/