PostgreSQLには「配列の配列」サポートが限られています
マニュアルを参照
これは "配列の配列"の制限された形式です。 Pavel(答え)によれば、「多次元配列」という名前が付けられていますが、実際は行列なので、各次元に同じ数の要素が必要です。
この種の構造体を科学的アプリケーションの多次元デカルト座標と多次元デカルト座標に使用できますが、XMLやJSONデータのようなベクトルの任意のベクトルを格納することはできません。
注:よく知られている2次元(2D)同種配列は、数学行列。実際、 "PostgreSQLの制約付き多次元配列"データ型を動機とした行列の科学的応用、そして配列はこれらの種類の配列で関数の動作をします。 「3D配列」は「3Dマトリックス」、「4D配列」は「4Dマトリックス」などと考えてください。
例:
SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[5,6]);
---------------------
{{1,2},{3,4},{5,6}}
SELECT array_cat(ARRAY[[1,2],[3,4]], ARRAY[[5,6]]); -- SAME RESULT
SELECT ARRAY[ARRAY[1,2],ARRAY[5,6]];
---------------
{{1,2},{5,6}}
SELECT array_cat(ARRAY[ARRAY[1,2]],ARRAY[3]); -- ERROR1
SELECT ARRAY[ARRAY[1,2],ARRAY[4]]; -- ERROR2
@Daniel_Lyonsの「なぜこれらがサポートされないのか」というコメントは、「配列の非一様な配列」に関するものです(上記のエラーケースを参照)。
上の ERROR1
:同じ次元の配列のみを連結できるため
ERROR2
:特定の次元のすべての配列は、行列のように同じ長さでなければなりません。
ビルドイン関数と演算子に関するもう一つの興味深いこと:PostgreSQLの "デフォルトの動作"は、単一の配列と要素のためのものです。標準的な array_append()
のオーバーロードはありません。
SELECT array_append(ARRAY[1,2],5); -- now ok, 5 is a element
{1,2,5}
SELECT array_cat(ARRAY[1,2], ARRAY[5,6]);
----------
{1,2,5,6}
SELECT array_append(ARRAY[[1,2],[3,4]], ARRAY[5,6]); -- ERROR3
SELECT array_append(ARRAY[1,2],ARRAY[5,6]); -- ERROR4
ERROR3
above: there are NO OVERLOAD to append "array element" (even 9.2 pg version).
ERROR4
above: must use array_cat to "merge all in one array".
最後の array_cat
の例の "マージの振る舞い"は興味深いものですが、配列の配列は生成されません。この結果を得るには array_cat(a1、ARRAY [a2])
を使用し、
SELECT array_cat(ARRAY[1,2], ARRAY[ARRAY[5,6]]); -- seems illogical...
---------------
{{1,2},{5,6}}
スパース行列
To avoid problems with スパース行列 and similar data structures, use the function below. It fills the remaining elements, setting then to NULL (or to any constant value).
CREATE FUNCTION array_fillTo(anyarray,integer,anyelement DEFAULT NULL)
RETURNS anyarray AS $$
DECLARE
i integer;
len integer;
ret ALIAS FOR $0;
BEGIN
len = array_length($1,1);
ret = $1;
IF len<$2 THEN
FOR i IN 1..($2-len) LOOP
ret = ret || $3;
END LOOP;
END IF;
RETURN ret;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
最初の例に戻って、エラーを回避できるようになりました(ERROR1を参照)。
SELECT array_cat(ARRAY[ARRAY[1,2]],array_fillTo(ARRAY[3],2));
{{1,2},{3,NULL}}