【发布时间】:2015-10-05 20:04:38
【问题描述】:
(以前也这样做过,但是记忆会消失,就像护目镜一样)
希望从users 中选择每个用户的tag.tag_ids 作为数组返回。
嵌入查询tag_arr 将是一个数组
【问题讨论】:
-
@a_horse_with_no_name - 是的。太多的语言,太多年了 - 谢谢
标签: arrays postgresql subquery aggregate-functions
(以前也这样做过,但是记忆会消失,就像护目镜一样)
希望从users 中选择每个用户的tag.tag_ids 作为数组返回。
嵌入查询tag_arr 将是一个数组
【问题讨论】:
标签: arrays postgresql subquery aggregate-functions
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 的执行时间。我不是数据库查询计划方面的专家,因此任何有关这两者如何以不同方式执行的见解都会有所帮助。
tags(usr_id) 上缺少索引,这对于第一个查询也很有用。
使用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。
【讨论】: