PostgreSQL:加入2个最大值为

时间:2015-09-28 09:04:50

标签: sql postgresql

我有一张包含2条记录的表(说明目的)

| id      | access (int array) |
| ---------------------------- |
| 1       | {0,1,0}            | 
| 2       | {1,0,0}            | 

我想选择两个值并将它们合并在一起 在这种情况下获得最高价值的结果:

{1,1,0}

访问阵列可能会增长到超过200个值,因此我想避免在编程代码中执行此操作(golang)。

基本上它与这个问题相同:Merge two (or more) arrays and keep values that are highest?但在我的情况下,分隔的列被组合成一个带有数组的字段。

更新

  1. row(access)数组总是具有相同数量的值

2 个答案:

答案 0 :(得分:1)

尝试此查询(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;

二进制数组

如果数组只包含' 0'和' 1'并且具有相同数量的值:

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) 

答案 1 :(得分:1)

请考虑以下为例:

create table arr(id int,access int[]);
insert into arr values (1,'{0,1,0}'),(2,'{0,1,0}'),(3,'{0,0,9}');

这样行将是:

id access  
-- ------- 
1  {0,1,0} 
2  {0,1,0} 
3  {0,0,9} 

现在可以创建一个函数来合并数组行,如下所示:

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

用法:select merge_array(3,'arr','access') 结果:

merge_array 
----------- 
{0,1,9}