【问题标题】:in postgres select, return a column subquery as an array?在 postgres 选择中,将列子查询作为数组返回?
【发布时间】:2015-10-05 20:04:38
【问题描述】:

(以前也这样做过,但是记忆会消失,就像护目镜一样)

希望从users 中选择每个用户的tag.tag_ids 作为数组返回。

选择 usr_id, 姓名, (从标签 t 中选择 t.tag_id,其中 t.usr_id = u.usr_id)作为 tag_arr 来自用户 u;

嵌入查询tag_arr 将是一个数组

【问题讨论】:

  • @a_horse_with_no_name - 是的。太多的语言,太多年了 - 谢谢

标签: arrays postgresql subquery aggregate-functions


【解决方案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 进行了比较,并分别得到了120ms10s 的执行时间。我不是数据库查询计划方面的专家,因此任何有关这两者如何以不同方式执行的见解都会有所帮助。
  • @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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-09
    • 2020-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 2015-03-15
    相关资源
    最近更新 更多