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つ づつにアクセスする方法は、下記のようになります。この問い合わせは、 第2四半期に給料が変わった従業員の名前を取り出します。
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"},{""}} |
+-------------------+