1

次の列を持つテーブルがあります。

(ID, row_num, col_num, pix_centroid, pix_val1). 

私は1000以上のレコードを持っています。以下を使用してデータを挿入しています。

insert into pixelbased (row_num, col_num, pix_centroid, pix_val)
select
    (ST_PixelAsPolygons(rast, 1)).x as X,
    (ST_PixelAsPolygons(rast, 1)).y as Y,
    (ST_Centroid((ST_PixelAsPolygons(rast, 1)).geom)) as geom,
    (ST_PixelAsPolygons(rast, 1)).val as pix_val1
from mytable 
where rid=1`

今、他のすべてのレコードを列として挿入しようとしていますが、_pix_val1_ 列は私にとって重要です。他のすべての列は同じままです。つまり、最終的なテーブルに次の列が必要です。

(ID, row_num, col_num, pix_centroid, pix_val1, pix_val2, pix_val3, ....)

それを行う方法はありますか?

4

1 に答える 1

2

可能であれば、このデータをバイトマップにビットマップとして保存したいと思います。一連のバイト値を取得してバイトに変換する方法は次のとおりです。

WITH bytes(b) AS (SELECT x % 256 FROM generate_series(1,53000) x)
SELECT ('\x'||string_agg(lpad(to_hex(b),2,'0'),''))::bytea FROM bytes;

関数を使用して、バイト配列のフィールドまたは範囲にアクセスできますsubstr。この bytea は、線形のピクセル配列として構成されていますが、従来のビットマップ形式に構成する方が便利な場合があります。また、ピクセルが 1 バイトを超える場合は、ビッグ エンディアンとリトルエンディアンに対処する必要がある場合があります。これは SQL で行うこともできますが、PL/Perl のような手続き型言語の方がはるかに簡単です。


そうでない場合は、多次元配列がやや合理的な選択になります。

generate_series便利なテストのためにフィールドの代わりにステートメントを使用するpix_valと、このクエリは 2 つの集計パスを使用して整数の 2 次元配列を生成します。

SELECT ('{'||string_agg(subarray, ',')||'}')::integer[] AS arr
FROM (
   SELECT array_agg(x order by x)::text 
   FROM generate_series(1,53000) x
   GROUP BY width_bucket(x, 1, 53001, 100)
) a(subarray);

array_agg2 次元配列の文字列リテラル形式の不幸な使用は、配列を集約できないという事実によって必要になります。私の見解では、これは PostgreSQL の本当の問題です。一般に、その多次元配列は扱いにくく、ほとんどのアプリケーションや言語が配列を実装する方法と矛盾しています。

配列にインデックスを付けることで、配列からフィールドを取得できます。例:

regress=> SELECT ('{'||string_agg(subarray, ',')||'}')::integer[] AS arr INTO test FROM (SELECT array_agg(x order by x)::text from generate_series(1,53000) x GROUP BY width_bucket(x, 1, 53001, 100)) a(subarray);

regress=> \d test

      Table "public.test"
 Column |   Type    | Modifiers 
--------+-----------+-----------
 arr   | integer[] | 

test2 次元の 1 つの配列が含まれます。

regress=> \x
regress=> select array_dims(test.arr), array_ndims(test.arr), array_length(test.arr,1), array_length(test.arr,2) FROM test;
-[ RECORD 1 ]+---------------
array_dims   | [1:100][1:530]
array_ndims  | 2
array_length | 100
array_length | 530

2 レベルのインデックスで要素を取得できます。

regress=> SELECT test.arr[4][4] FROM test;
 arr  
------
 1594
(1 row)

またはスライスした「列」:

regress=> SELECT test.arr[4:4][1:530] FROM test;

奇妙なことに、これはまだ 2 次元配列であり、最上位の次元は 1 要素の深さです。unnest必要に応じてandを使用して (非効率的に) フラット化できarray_aggます。

ご覧のとおり、PostgreSQL の 2 次元配列はやや奇妙ですが、あなたがやろうとしていることも同様です。

于 2012-10-31T02:20:48.650 に答える