将Postgresql数组连接到表

时间:2019-05-19 20:11:39

标签: sql postgresql

我有下表

create table top100
(
    id  integer   not null,    
    top100ids integer[] not null
);

create table top100_data
(
    id  integer   not null,    
    data_string text not null
);

top100中的行如下所示:
1, {1,2,3,4,5,6...100}
top100_data中的行如下所示:
1, 'string of text, up to 500 chars'

我需要从表top100_data中获取文本值,并将它们与表top100结合起来。
结果将是:
1, {'text1','text2','text3',...'text100'}

我目前正在应用程序方面这样做,方法是从top100中进行选择,然后迭代所有数组项,然后从top100_data中进行选择,然后再次迭代+将id转换为其_data的文本值。 在大型数据集上,这可能会非常慢。

是否可以通过单个SQL查询获得相同的结果?

2 个答案:

答案 0 :(得分:1)

您可以unnest()并重新汇总:

select t100.id, array_agg(t100d.data order by top100id)
from top100 t100 cross join
     unnest(top100ids) as top100id join
     top100_data t100d
     on t100d.id = top100id
group by t100.id;

或者如果您想保留原始顺序:

select t100.id, array_agg(t100d.data order by top100id.n)
from top100 t100 cross join
     unnest(top100ids) with ordinality as top100id(id, n) join
     top100_data t100d
     on t100d.id = top100id.id
group by t100.id;

答案 1 :(得分:0)

只需在PostgreSQL中使用unnestarray_agg函数,您的最终sql如下所示:

with core as (
select
    id,
    unnest(top100ids) as top_id
from
    top100
)
select
    t1.id,
    array_agg(t1.data_string) as text_datas
from
    top100 t1
join
    core c on t1.id = c.top_id

unnest的示例如下:

postgres=# select * from my_test;
 id |   top_ids    
----+--------------
  1 | {1,2,3,4,5}
  2 | {6,7,8,9,10}
(2 rows)

postgres=# select id, unnest(top_ids) from my_test;
 id | unnest 
----+--------
  1 |      1
  1 |      2
  1 |      3
  1 |      4
  1 |      5
  2 |      6
  2 |      7
  2 |      8
  2 |      9
  2 |     10
(10 rows)

array_agg的示例如下:

postgres=# select * from my_test_1 ;
 id | content 
----+---------
  1 | a
  1 | b
  1 | c
  1 | d
  2 | x
  2 | y
(6 rows)

postgres=# select id,array_agg(content) from my_test_1 group by id;
 id | array_agg 
----+-----------
  1 | {a,b,c,d}
  2 | {x,y}
(2 rows)