PostgreSQL矩阵转换

时间:2016-12-10 12:01:15

标签: arrays postgresql

我有一个名为test的PostgreSQL表,它有2列 - (1)id& (2)matrix如下: -

create table test (id integer, 
                   matrix double precision[]);

insert into test (id, matrix) values
    (1, '{ 0.1,  0.2,  0.3,  0.4}'),
    (2, '{-0.1, -0.2, -0.3, -0.4}'),
    (3, '{ 0.2, -0.2,  0.4, -0.4}'),
    (4, '{-0.5,  0.6, -0.7,  0.8}');

matrix总是 4,数量从-11不等。

我想将matrix转换为大小为8的数组 - 让我们称之为matrix_2。如果我们假设数组索引从1开始(PostgreSQL样式),那么: -

  • matrix_2[1]matrix[1]的绝对(正)值(但仅限于matrix[1] < 0
  • matrix_2[2]matrix[1]的值(但仅限于matrix[1] > 0)。
  • matrix_2[3]matrix_2[4]matrix[2]的值采用相同的模式,依此类推......)
  • 0数组中的matrix值变为0数组中2个条目中matrix_2的值。

SQL明智,这是我所拥有的: -

select 
    id, 
    matrix,   -- in purely for comparing numbers
    (
        case when matrix[1] < 0::double precision then @matrix[1] else 0::double precision end,
        case when matrix[1] > 0::double precision then matrix[1] else 0::double precision end,    
        case when matrix[2] < 0::double precision then @matrix[2] else 0::double precision end,
        case when matrix[2] > 0::double precision then matrix[2] else 0::double precision end,
        case when matrix[3] < 0::double precision then @matrix[3] else 0::double precision end,
        case when matrix[3] > 0::double precision then matrix[3] else 0::double precision end,
        case when matrix[4] < 0::double precision then @matrix[4] else 0::double precision end,
        case when matrix[4] > 0::double precision then matrix[4] else 0::double precision end
    ) as matrix_2
from 
    test;

返回以下内容: -

---------+-----------------------+--------------------------
id       | matrix                |  matrix_2
interger | double precision []   |  record
---------+-----------------------+--------------------------
1        | {0.1,0.2,0.3,0.4}     | (0,0.1,0,0.2,0,0.3,0,0.4)
2        | {-0.1,-0.2,-0.3,-0.4} | (0.1,0,0.2,0,0.3,0,0.4,0)
3        | {0.2,-0.2,0.4,-0.4}   | (0,0.2,0.2,0,0,0.4,0.4,0)
4        | {-0.5,0.6,-0.7,0.8}   | (0.5,0,0,0.6,0.7,0,0,0.8)
---------+-----------------------+--------------------------

查询以正确的顺序返回正确的值,但是: -

  1. matrix_2属于record类型 - 不是double precision []
  2. 的数组
  3. SQL查询非常可怕,即大量重复 - 可能会更加干涩。
  4. 有没有人对上述2点有任何建议?

1 个答案:

答案 0 :(得分:1)

您可以尝试下面的内容:

SELECT * 
FROM test,
LATERAL (
    SELECT array_agg( val ) As matrix_2
    FROM (
        SELECT xxx, 1 as ord, 
               case when  matrix[ xxx ] < 0 then abs(matrix[ xxx ]) else 0 end as val
        FROM generate_subscripts( matrix, 1) xxx
        UNION ALL
        SELECT xxx, 2 as ord, 
               case when  matrix[ xxx ] > 0 then abs(matrix[ xxx ]) else 0 end as val
        FROM generate_subscripts( matrix, 1) xxx
        ORDER BY xxx, ord
    ) q
) x;