在 postgres 选择中,将列子查询作为数组返回?
Posted
技术标签:
【中文标题】在 postgres 选择中,将列子查询作为数组返回?【英文标题】:in postgres select, return a column subquery as an array? 【发布时间】:2015-10-05 20:04:38 【问题描述】:(以前也这样做过,但是记忆会消失,就像护目镜一样)
希望从users
中选择每个用户的tag.tag_id
s 作为数组返回。
嵌入查询tag_arr
将是一个数组
【问题讨论】:
@a_horse_with_no_name - 是的。太多的语言,太多年了 - 谢谢 【参考方案1】:使用aggregate function:
select
usr_id,
name,
array_agg(tag_id) as tag_arr
from users
join tags using(usr_id)
group by usr_id, name
或来自子查询结果的array constructor:
select
u.usr_id,
name,
array(
select tag_id
from tags t
where t.usr_id = u.usr_id
) as tag_arr
from users u
第二个选项是一个简单的单源查询,而第一个更通用,当您需要来自相关表的多个聚合时特别方便。此外,第一个变体在较大的表上应该更快。
注意,为了获得更好的性能,两个表中的usr_id
列都应该被索引。虽然users.usr_id
通常是主键,但有时可能会忘记引用列的索引也很有用。
【讨论】:
在这两个选项中,使用array_agg()
的第一个选项的执行时间会明显更好吗?我认为这取决于所涉及的数据表的大小。在一个实际项目中,我只是将这两个查询与explain analyze
进行了比较,并分别得到了120ms
和10s
的执行时间。我不是数据库查询计划方面的专家,因此任何有关这两者如何以不同方式执行的见解都会有所帮助。
@broc.seib - 这取决于许多因素,例如两个表中的行数、每个用户的平均标签数、Postgres 版本、服务器和硬件配置。对于较大的表,第一个查询应该比另一个查询快。不过,您的情况差异似乎太大了。原因可能是tags(usr_id)
上缺少索引,这对于第一个查询也很有用。【参考方案2】:
使用PostgreSQL的array
构造函数:
select
usr_id,
name,
array(select t.tag_id from tags t where t.usr_id = u.usr_id) as tag_arr
from users u;
注意:
如果您将psycopg2
与python 一起使用,那么结果也将转换为python list
! (虽然对于uuid[]
数组,如果您想在python 列表中获取ID,则需要使用array(...)::text[]
将其转换为text[]
数组)。详情请见this。
【讨论】:
以上是关于在 postgres 选择中,将列子查询作为数组返回?的主要内容,如果未能解决你的问题,请参考以下文章
如何插入选择查询的结果(如果不返回任何行则默认)作为 Postgres 函数的一部分?