★PostgreSQLカンファレンス2024 12月6日開催/チケット販売中★
他のバージョンの文書 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

9.23. 行と配列の比較

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

9.23.1. IN

expression IN (value [, ...])

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

expression = value1
OR
expression = value2
OR
...

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

9.23.2. NOT IN

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

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

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

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

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

9.23.3. ANY/SOME (array)

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

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

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

SOMEANYの同義語です。

9.23.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.23.5. 行に関しての比較

row_constructor operator row_constructor

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

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

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

row_constructor IS NOT DISTINCT FROM row_constructor

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

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