sql - 使用基本项查询从连接表中进行选择的有效技术?

标签 sql postgresql

我有一个非常标准的数据库设置,其中包含父子关系。类似于父表、子表和 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/

相关文章:

sql - 从本地 WCF 连接到 Azure SQL 数据库

sql - postgreSQL 选择昨天的值,月平均值

postgresql - 如何使用 rust-postgres 检查列是否为 NULL?

postgresql - Redshift : Any ways to compute fuzzy string similarity/string edit distance?

PostgreSQL 无法删除分区上的索引

database - 查找每个 ID 出现的天数

java - 使用 SQL REGEXP 查找手机号码

sql - 合并日期和时间列

postgresql - Postgres 以错误的顺序返回记录

php - 自动增加员工ID