9.16. 副問い合わせ式

本節ではPostgreSQLで使用できるSQL準拠の副問い合わせについて説明します。 本節で記載したすべての式は結果として論理値(真/偽)を返します。

9.16.1. EXISTS

EXISTS ( subquery )

EXISTSの引数は、任意のSELECT文または副問い合わせです。 副問い合わせはそれが何らかの行を返すか否かの決定のために評価されます。 もし一つでも行を返すのであれば、EXISTSの結果は"真"となり、副問い合わせが行を返さない場合、EXISTSの結果は"偽"となります。

問い合わせは、その回りの問い合わせ内の変数を参照することができます。 その値は副問い合わせの評価時には定数として扱われます。

副問い合わせは最後の完結まで行かずに、一般的に少なくとも一つの行が返されたかどうかを判定し得るに足りる時点まで実行されます。 実際に副作用がなされるか否かを予想するのは難しいので、(シーケンス関数を呼び出すような)何らかの副作用を持つ副問い合わせを記述することはお勧めしません。

結果は何らかの行が返されるのかに依存し、それらの行の内容には依存しないことから、副問い合わせの出力リストは通常興味のあるものではありません。 良く使われるコーディング規約は、すべてのEXISTSテストをEXISTS(SELECT 1 WHERE ...)といった形式で記述することです。 とは言っても、INTERSECTを使う副問い合わせのようにこの規則には例外があります。

以下の平易な例はcol2上の内部結合のようですが、たとえtab2の行と複数一致したとしてもtab1のそれぞれの行に対して多くても一つの出力行を生成します。

SELECT col1 FROM tab1
    WHERE EXISTS(SELECT 1 FROM tab2 WHERE col2 = tab1.col2);

9.16.2. IN

expression IN (subquery)

右辺は括弧で括られた副問い合わせで、正確に1列を返すものでなければなりません。 左辺式は評価され、副問い合わせの結果行と比較されます。 副問い合わせの行のどれかと等しい場合、INの結果は"真"です。 (副問い合わせが行を返さない特別の場合を含め)等しい行が見つからない場合、結果は"偽"です。

左辺の式がNULLを生じる場合、または右側の値に等しいものが無くて少なくとも一つの右辺の行がNULLを持つ場合、IN構文の結果は偽では無くNULLとなります。 これは、NULL値の論理的な組合せに対するSQLの通常の規則に従うものです。

EXISTSと同様、副問い合わせが完全に評価されると前提してはなりません。

(expression [, expression ...]) IN (subquery)

INのこの形式の右辺は括弧で括られた副問い合わせで、左辺のリストにある式の数と正確に同じ数の列を返さなければなりません。 左辺の式は副問い合わせの結果のそれぞれの行に対し、行に関して評価、比較が行なわれます。 副問い合わせの行に等しいものが見つかった場合、IN の結果は"真"となります。 (副問い合わせが行を返さない特別の場合を含め)等しい行が見つからない場合、結果は"偽"です。

いつもの通り、行にあるNULL値は、SQLの論理式の通常規則で結合されます。 二つの行は対応するすべての構成要素が非NULLかつ等しい場合に等しいと見做されます。 1つでも対応する構成要素が非NULLかつ等しくないものがあれば、2つの行は等しくないと見做されます。 それ以外その行の比較結果は不明(NULL)です。 すべての行の結果が非等もしくはNULLの場合、少なくとも一つのNULLがあると、IN の結果はNULLとなります。

9.16.3. NOT IN

expression NOT IN (subquery)

右辺は括弧で括られた副問い合わせで、正確に1つの列を返さなければなりません。 左辺の式は副問い合わせ結果の行それぞれに対して評価、比較されます。 (副問い合わせが行を返さない特別な場合を含む)等しくない副問い合わせの行だけがあると、NOT INの結果は"真"です。 等しい行が1つでもあれば、結果は"偽"です。

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

EXISTSと同様、副問い合わせが完全に評価されると前提してはなりません。

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

NOT INのこの形式の右辺は括弧で括られた副問い合わせで、左辺のリストにある式の数と正確に同じ数の列を返さなければなりません。 左辺の式は副問い合わせの結果のそれぞれの行に対し、評価、比較が行なわれます。 (副問い合わせが行を返さない特別の場合を含め)副問い合わせの行に非等のもののみが見つかった場合、NOT INの結果は"真"となります。 等しい行が1つでも見つかった場合、結果は"偽"です。

いつもの通り、行にあるNULL値は、SQLの論理式の通常規則で結合されます。 二つの行は対応するすべての構成要素が非NULLかつ等しい場合に等しいと見做されます。 一つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないと見做されます。 それ以外その行の比較結果は不明(NULL)です。 すべての行の結果が非等もしくはNULLの場合、少なくとも一つのNULLがあると、NOT INの結果はNULLとなります。

9.16.4. ANY/SOME

expression operator ANY (subquery)
expression operator SOME (subquery)

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

SOMEANYの同義語です。 IN= ANYと等価です。

成功したものがなく、右辺の行が演算子の結果として1つでもNULLを生成した場合、ANY構文の結果は偽ではなくNULLになります。 これは、NULL値の論理的な組合せに対するSQLの通常の規則に従うものです。

EXISTSと同様、副問い合わせが完全に評価されると前提してはなりません。

(expression [, expression ...]) operator ANY (subquery)
(expression [, expression ...]) operator SOME (subquery)

ANYのこの形式の右辺は括弧で括られた副問い合わせで、左辺のリストにある式の数と正確に同じ数の列を返さなければなりません。 左辺の式は副問い合わせの結果のそれぞれの行に対し、与えられたoperatorを使用して行に関する評価、比較が行なわれます。 現時点では、行に対するANY問い合わせで=<>のみ認められています。 それぞれ等値もしくは非等の行が見つかればANYの結果は"真"となります。 (副問い合わせが行を返さない特別の場合を含め)そのような行が見つからない場合、結果は"偽"です。

いつもの通り、行にあるNULL値は、SQLの論理式の通常規則で結合されます。 二つの行は対応するすべての構成要素が非NULLかつ等しい場合に等しいと見做されます。 一つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないと見做されます。 それ以外その行の比較結果は不明(NULL)です。 1つでもNULL行結果があると、ANYは偽にはなることはできず、真かNULLになります。

9.16.5. ALL

expression operator ALL (subquery)

右辺は括弧で括られた副問い合わせで、正確に1つの列を返さなければなりません。 左辺の式は副問い合わせの結果行それぞれに対して、指定されたoperatorを使用して評価、比較されます。 なお、operatorは結果として論理値を生成する必要があります。 (副問い合わせが行を返さない特別な場合を含む)すべての行が真になる場合、ALLの結果は"真"です。 1つでも偽の結果があると、結果は"偽"です。

NOT IN<> ALLと等価です。

失敗したものがなく、右辺の行が演算子の結果として1つでもNULLを生成した場合、ALL構文の結果は真ではなくNULLになります。 これは、NULL値の論理的な組合せに対するSQLの通常の規則に従うものです。

EXISTSと同様、副問い合わせが完全に評価されると前提してはなりません。

(expression [, expression ...]) operator ALL (subquery)

ALLのこの形式の右辺は括弧で括られた副問い合わせで、左辺のリストにある式の数と正確に同じ数の列を返さなければなりません。 左辺の式は副問い合わせの結果のそれぞれの行に対し、与えられたoperatorを使用して行に関する評価、比較が行なわれます。 現時点では、行に対するALL問い合わせで=<>演算子のみ認められています。 (副問い合わせが行を返さない特別の場合を含め)それぞれすべての副問い合わせの行が等値もしくは非等であればALLの結果は"真"となります。 それぞれ非等、もしくは等しい行が1つでもあれば、結果は"偽"です。

いつもの通り、行にあるNULL値は、SQLの論理式の通常規則で結合されます。 二つの行は対応するすべての構成要素が非NULLかつ等しい場合に等しいと見做されます。 一つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないと見做されます。 それ以外その行の比較結果は不明(NULL)です。 1つでもNULL行結果があると、ALLは真にはなることはできず、偽かNULLになります。

9.16.6. 行に関しての比較

(expression [, expression ...]) operator (subquery)

左辺はスカラ式のリストです。 右辺は括弧で括られた副問い合わせで、左辺の式とまったく同じ数の列を返さなければなりません。 さらに、副問い合わせは一行以上返すことはできません。 (行をまったく返さない場合、結果はNULLと見なされます。) 左辺は副問い合わせの結果の単一行に対し行全体で評価、比較が行なわれます。 現時点では、行に対する比較において=<>のみ認められています。 それぞれ2つの行が等しいもしくは等しくない場合、結果は"真"となります。

いつもの通り、行にあるNULL値は、SQLの論理式の通常規則で結合されます。 二つの行は対応するすべての構成要素が非NULLかつ等しい場合に等しいと見做されます。 一つでも構成要素が非NULLかつ等しくない場合、2つの行は等しくないと見做されます。 それ以外その行の比較結果は不明(NULL)です。