PostgreSQL JOIN with array type with array elements order, how to implement?
Asked Answered
D

5

91

I have two tables in database:

CREATE TABLE items(
 id SERIAL PRIMARY KEY,
 ... some other fields
);

This table contains come data row with unique ID.

CREATE TABLE some_chosen_data_in_order(
 id SERIAL PRIMARY KEY,
 id_items INTEGER[],
);

This table contains array type field. Each row contains values of IDs from table items in specific order. For example: {2,4,233,5}.

Now, I want to get data from table items for chosen row from table some_chosen_data_in_order with order for elements in array type.

My attempt was JOIN:

SELECT I.* FROM items AS I 
JOIN some_chosen_data_in_order AS S ON I.id = ANY(S.id_items) WHERE S.id = ?

Second attempt was subquery like:

SELECT I.* FROM items AS I 
WHERE I.id = ANY 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])

But none of them keep IDs in the same order as in array field. Could you help me, how to get data from items table with correspond with array IDs order from some_chosen_data_in_order table for specific row?

Detector answered 21/3, 2010 at 10:36 Comment(0)
G
146
SELECT t.*
FROM unnest(ARRAY[1,2,3,2,3,5]) item_id
LEFT JOIN items t on t.id=item_id

The above query select items from items table with ids: 1,2,3,2,3,5 in that order.

Ginkgo answered 4/9, 2012 at 16:32 Comment(5)
unnest() is a really cool trick! I had a list of ID's from a customer and needed to join against them but wanted to find a way to do it w/o a temp table. You can join (select unnest(ARRAY[1,2,3])) as idlist and it works like a champ. thanks!Mulish
@Mulish can you please show me the query? still dint get itChattanooga
If you want to join two tables with each other you could for instance use SELECT b.*, a.item_id FROM (SELECT unnest(array_column_in_table_a) item_id FROM table_a) as a RIGHT JOIN table_b b on b.id=a.item_id;Seafarer
I needed to join to tables, but the above comment didn't work for me, but this did: SELECT * FROM table_a a JOIN table_b b ON b.id = ANY(a.array_column_in_table_a);, thanks to garysieling.com/blog/postgres-join-on-an-array-fieldGraybill
This doesn't match the question, why was it chosen?Thora
C
58

Probably normalizing your table would be the best advice I can give you.

The int_array contrib module has an idx function that will give you the int's index position in the array. Also there is an idx function on the snippets wiki that works for array's of any data types.

SELECT i.*, idx(id_items, i.id) AS idx
FROM some_chosen_data_in_order s
JOIN items i ON i.id = ANY(s.id_items)
ORDER BY idx(id_items, i.id)
Condon answered 22/3, 2010 at 3:1 Comment(2)
Works, thanks. The order by clause works with just idx as well.Thora
where s.id = ? -- an id numberThora
E
8
select distinct on (some_chosen_data_in_order.id)
  some_chosen_data_in_order.*,
   array_to_json( array_agg(row_to_json( items))
  over ( partition by some_chosen_data_in_order.id ))
from some_chosen_data_in_order
  left join items on items.id = any (some_chosen_data_in_order.id_items)

enter image description here

Expedient answered 27/4, 2018 at 4:59 Comment(0)
R
4

If you don't like functions (https://mcmap.net/q/234496/-postgresql-join-with-array-type-with-array-elements-order-how-to-implement):

SELECT jt.*
FROM (
     SELECT ARRAY_AGG(DISTINCT dupes_column) AS unique_vals
     FROM dupes_table
) q
LEFT JOIN joined_table jt
ON jt.id = ANY(q.unique_vals);
Ripping answered 14/7, 2021 at 11:2 Comment(0)
S
2
SELECT I.* FROM items AS I 
WHERE I.id IN (SELECT UNNEST(id_items) FROM some_chosen_data_in_order 
(ARRAY[SELECT S.id_items FROM some_chosen_data_in_order  WHERE id = ?])
Saez answered 28/5, 2015 at 18:3 Comment(1)
When adding code as answer, then add a bit explanation to your answer for future readers..Gaselier

© 2022 - 2024 — McMap. All rights reserved.