Reputation: 2119
I have an table with 2 records ( illustrative purpose )
| id | access (int array) |
| ---------------------------- |
| 1 | {0,1,0} |
| 2 | {1,0,0} |
I'd like to select both values and merge them together
to get the highest value making the result in this case:
{1,1,0}
The access array could grow to over 200 values and therefor i'd like to avoid to do it in the programming code, ( golang ).
Basically it is the same as this question : Merge two (or more) arrays and keep values that are highest? but in my case the seperated columns are combined into one field with an array.
UPDATES
row(access)
array's always have the same amount of valuesUpvotes: 3
Views: 208
Reputation: 121634
Try this query (SqlFiddle):
select array_agg(elem)
from (
select distinct on (row_number) row_number, elem
from (
select id, elem, row_number() over (partition by id)
from (
select id, unnest(access) elem
from merge_test
where id in (1,2)
) sub
) sub
order by 1, 2 desc
) sub;
Binary arrays
If the arrays contain only '0' and '1' and have the same number of values:
create table merge_binary_test (id int, access int[]);
insert into merge_binary_test values
(1, '{0,1,0,1}'),
(2, '{1,0,0,1}');
select string_to_array(bit_or(elem)::text, null)::int[]
from (
select id, array_to_string(access, '')::varbit elem
from merge_binary_test
where id in (1,2)
) sub
string_to_array
-----------------
{1,1,0,1}
(1 row)
Upvotes: 1
Reputation: 21915
Consider following as an example:
create table arr(id int,access int[]);
insert into arr values (1,'{0,1,0}'),(2,'{0,1,0}'),(3,'{0,0,9}');
so that the rows will be:
id access
-- -------
1 {0,1,0}
2 {0,1,0}
3 {0,0,9}
Now a function can be created to merge array rows like below:
CREATE
OR replace FUNCTION merge_array (
arrval INT -- the total number of values in an array in my example its 3, but 200 is for yours
,tbl TEXT --name of the table in which you want perform this function,
,col TEXT -- name of the array col
)
RETURNS setof INTEGER [] AS $$
DECLARE qry TEXT;
BEGIN
SELECT format('select translate(string_to_array(x.*::text,'','')::text,''()'','''')::int[] from (select %s from (select ' || col || ' ar from ' || tbl || ' ) as sq) as x ', egn)
INTO qry
FROM (
SELECT string_agg('max(ar[' || val || '])', ',') egn
FROM (
SELECT generate_series(1, arrval) val
) t
) tt;
RETURN QUERY
EXECUTE (qry);
END;$$
LANGUAGE plpgsql
Usage : select merge_array(3,'arr','access')
Result:
merge_array
-----------
{0,1,9}
Upvotes: 1