5.2. 非原子的データ値

リレーショナルモデルの主義の1つは、テーブルの行は原子的であるということです。 Postgresではこの制約がありません。 行は問い合わせ言語からアクセスされることが可能な部分値を 含むことができます。例えば、基本型が配列である行を作成することできます。

5.2.1. 配列

Postgresでは、列の行は 固定長あるいは可変長の多次元配列を定義することが可能です。 いかなる基本型、またはユーザ定義型である配列か作成可能です。 それらの使用法を説明するために、例としてまず既存の型の 配列のクラスを作成します。

CREATE TABLE SAL_EMP (
    name            text,
    pay_by_quarter  integer[],
    schedule        text[][]
);
     

上記の問い合わせは、SAL_EMPというテーブルを作成し、 氏名を表すtext型文字列(name)、 従業員の4半期毎の給料を表すinteger型 一次元配列(pay_by_quarter)、従業員の1週間のスケジュールを表す text 型二次元配列(schedule)が作成されます。 そこに幾つかのINSERT文を実行してみます。 配列へデータを追加する時には、値を括弧で囲み、そしてそれらをカンマで 区切ることに注意してください。Cをご存知な方は 構造体を初期化する構文と同じことに気づかれるでしょう。

INSERT INTO SAL_EMP
    VALUES ('Bill',
    '{10000, 10000, 10000, 10000}',
    '{{"meeting", "lunch"}, {}}');

INSERT INTO SAL_EMP
    VALUES ('Carol',
    '{20000, 25000, 25000, 25000}',
    '{{"talk", "consult"}, {"meeting"}}');
     
Postgresではデフォルトで 配列の番号付け規約に"1始まり"を起用しています。 それはつまりn個要素の有る配列は、array[1]で始まり、 array[n]で終わります。ここで、SAL_EMPテーブルに対し 問い合わせが行ってみます。まず、一度に1つの配列の 要素にアクセスする方法は、下記のようになります。
SELECT name
    FROM SAL_EMP
    WHERE SAL_EMP.pay_by_quarter[1] <>
    SAL_EMP.pay_by_quarter[2];

+------+
|name  |
+------+
|Carol |
+------+
     

また、下記の問い合わせは全ての従業員の第 3四半期の給料を検索します。

SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;


+---------------+
|pay_by_quarter |
+---------------+
|10000          |
+---------------+
|25000          |
+---------------+
     

同様に、それぞれのサブスクリプトの上限/下限を指定することによって、 配列/副配列の任意の部分を取り出すことも可能です。 下記の問い合わせは、週の始めの2日間のBillさんのスケジュールにある、 最初の項目を検索します。

SELECT SAL_EMP.schedule[1:2][1:1]
    FROM SAL_EMP
    WHERE SAL_EMP.name = 'Bill';

+-------------------+
|schedule           |
+-------------------+
|{{"meeting"},{""}} |
+-------------------+