行と配列の比較

PostgreSQL 8.4.1文書
前のページ | 巻戻し | 第 9章関数と演算子 | 早送り | 次のページ

# 9.21. 行と配列の比較

本節では、値のグループ間で複数の比較を行う、さまざまな特殊化したコンストラクトについて説明します。この形式は構文的には、前節の副問い合わせ形式と関係しています。しかし、副問い合わせを含みません。配列副式を含むこの形式はPostgreSQLの拡張です。この他はSQL準拠です。本節で記載した全ての式形式は結果として論理値（真/偽）を返します。

## 9.21.1. `IN`

    expression IN (value [, ...])

右辺は括弧で括られたスカラ式のリストです。左辺の式の結果が右辺の式のいずれかと等しい場合、結果は"true（真）"になります。これは以下の省略形です。

    expression = value1
    OR
    expression = value2
    OR
    ...

左辺の式がNULLを生じる場合、または右側の値に等しいものがなくて少なくとも1つの右辺の行がNULLを持つ場合、`IN`構文の結果は偽ではなくNULLとなることに注意してください。これは、NULL値の論理的な組み合わせに対するSQLの標準規則に従うものです。

## 9.21.2. `NOT IN`

    expression NOT IN (value [, ...])

右辺は括弧で括られたスカラ式のリストです。左辺の式の結果が右辺の式の全てと等しくない場合、結果は"真"です。これは以下の省略形です。

    expression <> value1
    AND
    expression <> value2
    AND
    ...

左辺の式でNULLが生じる場合、または右側の値に等しいものがなく、少なくとも1つの右辺の式がNULLを生み出す場合、予想通り`NOT IN`構文の結果は真ではなくNULLとなることに注意してください。これは、NULL値の論理的な組み合わせに対するSQLの標準規則に従うものです。

> ティップ: 全ての場合において、`x NOT IN y`は`NOT (x IN y)`と等価です。しかし、`IN`を使用するよりも`NOT IN`を使用する方が初心者がNULL値による間違いをしやすくなります。可能な限り条件を肯定的に表現することが最善です

## 9.21.3. `ANY`/`SOME` (array)

    expression operator ANY (array expression)
    expression operator SOME (array expression)

右辺は括弧で括られた式で、配列値を返さなければなりません。左辺の式は配列要素それぞれに対して、指定された`operator`を使用して評価、比較されます。なお、`operator`は結果として論理値を生成する必要があります。真の結果が１つでもあると、`ANY`の結果は"true（真）"です。（配列の要素数がゼロである場合を含み）真の結果がないと、結果は"false（偽）"です。

配列式がNULL配列を生成する場合、`ANY`の結果はNULLになります。左辺式がNULLとなる場合、`ANY`の結果は通常NULLになります。（あまり厳密でない比較演算子では異なる結果になるかもしれません。）また、右辺の配列にNULL要素が含まれ、かつ、比較した結果真でない値になった場合、`ANY`の結果は偽ではなくNULLになります。（繰り返しになりますが、厳密な演算子の場合です。）これは、NULLに対する、SQLの論理値組み合わせに関する標準規則に従うものです。

`SOME`は`ANY`の同義語です。

## 9.21.4. `ALL` (array)

    expression operator ALL (array expression)

右辺は括弧で括られた式で、配列値を返さなければなりません。左辺の式は配列の要素それぞれに対して、指定された`operator`を使用して評価、比較されます。なお、`operator`は結果として論理値を生成する必要があります。（配列の要素数がゼロである場合を含み）全ての比較が真になる場合、`ALL`の結果は"true（真）"です。1つでも偽の結果があると、結果は"false（偽）"です。

配列式がNULL配列を生成する場合、`ALL`の結果はNULLになります。左辺式がNULLとなる場合、`ALL`の結果は通常NULLになります。（厳密でない比較演算子では異なる結果になるかもしれません。）また、右辺の配列にNULL要素が含まれ、かつ、比較した結果偽でない値になった場合、`ALL`の結果は真ではなくNULLになります。（繰り返しになりますが、厳密な演算子の場合です。）これは、NULLに対する、SQLの論理値組み合わせに関する標準規則に従うものです。

## 9.21.5. 行に関しての比較

    row_constructor operator row_constructor

両辺とも項4.2.12で説明する行コンストラクタです。この２つの行値は同じフィールド数でなければなりません。両辺はそれぞれ評価され、行として比較されます。行の比較は、`operator`が`=`、`<>`、`<`、`<=`、`>`、`>=`の場合、または、これらのうちの１つと同じ意味を持つ場合に認められます。（より具体的には、演算子がB-Tree演算子クラスのメンバ、または、B-Tree演算子クラスの`=`メンバの否定子であれば、行比較演算子となることができます。）

`=`と`<>`の場合、他と動作が多少異なります。2つの行は対応する全ての構成要素が非NULLかつ等しい場合に等しいとみなされます。１つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないとみなされます。それ以外その行の比較結果は不明（NULL）です。

`<`、`<=`、`>`、`>=`の場合、行の要素は左から右に比較されます。そして、不等またはNULLの組み合わせが見つかったところで停止します。要素の組み合わせのどちらかがNULLであった場合、行比較の結果は不明（NULL）です。さもなくば、要素の組み合わせの比較により結果が決まります。例えば、`ROW(1,2,NULL) < ROW(1,3,0)`は、３番目の要素の組み合わせまで進まないため、NULLではなく真を返します。

> 注意: PostgreSQL 8.2以前では、`<`、`<=`、`>` 、`>=`の場合SQL仕様に従っていませんでした。`ROW(a,b) < ROW(c,d)`などの比較は正しくは`a < c OR (a = c AND b < d)`ですが、`a < c AND b < d`として実装されていました。

    row_constructor IS DISTINCT FROM row_constructor

このコンストラクトは`<>`行比較と類似していますが、NULL入力に対してNULLを生成しない点が異なります。その代わりに、全てのNULL値は非NULL値と等しくない（DISTINCT FROM）ものとみなされ、また、２つのNULLは等しい（NOT DISTINCT）ものとみなされます。したがって、結果は真か偽のいずれかで、NULLにはなりません。

    row_constructor IS NOT DISTINCT FROM row_constructor

このコンストラクトは`=`行比較と類似していますが、NULL入力に対してNULLを生成しません。代わりに、NULL値を、すべての非NULLの値に対して不等（DISTINCT FROM）とみなし、２つのNULLを等しいもの（NOT DISTINCT）とみなします。したがって、結果は常に真か偽となり、NULLになることはありません

> 注意: SQL仕様は、結果がNULL値、またはNULLと非NULLの比較に基づくのであれば、行の観点からの比較を必要とします。PostgreSQLは、２つの行構成子の出力の比較を行う時、または副問い合わせの出力に対し（項9.20にあるように）行構成子の比較を行う時のみこれを実施します。２つの複合型の値が比較されるほかの状況では、２つのNULLフィールドの値は等しいと考えられ、NULLは非NULLより大きいとみなされます。複合型に対して、これは一貫した並び替えとインデックス付け動作担保のため必要です。

前のページ | ホーム | 次のページ
副問い合わせ式 | 上に戻る | 集合を返す関数