本節では、値グループ間の複数の比較を行う、複数の特別な構文について説明します。この形式は構文的には、前節の副問い合わせ形式と関係しています。しかし、副問い合わせを含みません。配列副式を含むこの形式はPostgreSQLの拡張です。この他はSQL準拠です。本節で記載した全ての式は結果として論理値(真/偽)を返します。
expression IN (value [, ...])
右辺は括弧で括られたスカラ式のリストです。左辺の式の結果が右辺の式のいずれかと等しい場合、結果は"真"になります。これは以下の省略形です。
expression = value1 OR expression = value2 OR ...
左辺の式がNULLを生じる場合、または右側の値に等しいものがなくて少なくとも1つの右辺の行がNULLを持つ場合、IN構文の結果は偽ではなくNULLとなります。これは、NULL値の論理的な組み合わせに対するSQLの通常の規則に従うものです。
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値による間違いをしやすくなります。可能な限り条件を肯定的に表現することが最善です。
expression operator ANY (array expression) expression operator SOME (array expression)
右辺は括弧で括られた式で、配列値を返さなければなりません。左辺の式は配列要素それぞれに対して、指定されたoperatorを使用して評価、比較されます。なお、operatorは結果として論理値を生成する必要があります。真の結果が1つでもあると、ANYの結果は"真"です。(配列の要素数がゼロである特別な場合を含む)真の結果がないと、結果は"偽"です。
配列式がNULL配列を生成する場合、ANYの結果はNULLになります。 左辺式がNULLとなる場合、ANYの結果は通常NULLになります。 (あまり厳密でない比較演算子では異なる結果になるかもしれません。) また、右辺の配列にNULL要素が含まれ、かつ、比較した結果真でない値になった場合、ANYの結果は偽ではなくNULLになります。 (繰り返しになりますが、厳密な演算子の場合です。) これは、NULLに対する、SQLの論理値組み合わせに関する通常の規則に従っています。
SOMEはANYの同義語です。
expression operator ALL (array expression)
右辺は括弧で括られた式で、配列値を返さなければなりません。左辺の式は配列の要素それぞれに対して、指定されたoperatorを使用して評価、比較されます。なお、operatorは結果として論理値を生成する必要があります。(配列の要素数がゼロである特別な場合を含む)全ての比較が真になる場合、ALLの結果は"真"です。1つでも偽の結果があると、結果は"偽"です。
配列式がNULL配列を生成する場合、ALLの結果はNULLになります。 左辺式がNULLとなる場合、ALLの結果は通常NULLになります。 (あまり厳密でない比較演算子では異なる結果になるかもしれません。) また、右辺の配列にNULL要素が含まれ、かつ、比較した結果偽でない値になった場合、ALLの結果は真ではなくNULLになります。 (繰り返しになりますが、厳密な演算子の場合です。) これは、NULLに対する、SQLの論理値組み合わせに関する通常の規則に従っています。
row_constructor operator row_constructor
両辺とも項4.2.11で説明する行コンストラクタです。 この2つの行値は同じフィールド数でなければなりません。 両辺はそれぞれ評価され、行として比較されます。 行の比較は、operatorが=、<>、<、<=、>、>=の場合、または、これらと同じ意味を持つ(仕様としては、演算子がB-Tree演算子クラスのメンバ、または、B-Tree演算子クラスの=メンバの否定子であれば、行比較演算子となることができます。)場合に行うことができます。 ()
=と<>の場合、他と動作が多少異なります。 2つの行は対応する全ての構成要素が非NULLかつ等しい場合に等しいとみなされます。1つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないとみなされます。それ以外その行の比較結果は不明(NULL)です。
<、<=、>、>=の場合、行の要素は左から右に比較されます。 そして、不等またはNULLの組み合わせが見つかったところで停止します。 要素の組み合わせのどちらかがNULLであった場合、行比較の結果は不明(NULL)です。 さもなくば、要素の組み合わせの比較により結果が決まります。 例えば、ROW(1,2,NULL) < ROW(1,3,0)は真を返します。 3番目の要素の組み合わせまで進まないためです。
注意: 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値は非ULL値と等しくない(異なる)ものとみなされ、また、2つのNULLは等しい(異ならない)ものとみなされます。したがって、結果は常に真か偽となり、NULLにはなりません。
row_constructor IS NOT DISTINCT FROM row_constructor
この構文は=行比較とにていますが、NULL入力に対してNULLを生成しません。 代わりに、NULL値を、すべての非NULLの値に対して(異なるものとして)不等とみなし、2つのNULLを(区別せずに)等しいものとみなします。 したがって、結果は常に真か偽となり、NULLになることはありません。