2

I have following tables

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

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

Rows in table top100 look like:
1, {1,2,3,4,5,6...100}
Rows in table top100_data look like:
1, 'string of text, up to 500 chars'

I need to get the text values from table top100_data and join them with table top100.
So the result will be:
1, {'text1','text2','text3',...'text100'}

I am currenly doing this on application side by selecting from top100, then iterating over all array items and then selecting from top100_data and iterating again + transforming ids to their _data text values. This can be very slow on large data sets.

Is is possible to get this same result with single SQL query?

2 Answers 2

3

You can unnest() and re-aggregate:

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;

Or if you want to keep the original ordering:

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;
Sign up to request clarification or add additional context in comments.

Comments

0

Just use unnest and array_agg function in PostgreSQL, your final sql could be like below:

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

The example of unnest as below:

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)

The example of array_agg as below:

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.