6.15. 副問い合わせ式

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

6.15.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);

6.15.2. IN (scalar form)

expression IN (value[, ...])

IN のこの形式の右側はスカラー式が丸括弧で括られたリストです。 左側の式の結果が右側の式のどれかと等しい場合、結果は「真」です。 これは、次の表記法の簡略形です。

expression = value1
OR
expression = value2
OR
...

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

Note: この IN の形式は本当は副問い合わせ式ではありませんが、副問い合わせ IN と同じ所に文書化するのが最適のようです。

6.15.3. IN (subquery form)

expression IN (subquery)

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

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

EXISTS と同じように副問い合わせが最後まで評価されると思い込むのは賢くありません。

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

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

いつもの通り、式または副問い合わせの行にある NULL 値は、SQL の論理式の通常ルールで結合されます。 二つの行は対応するすべての構成要素が非 NULL で且等しい場合に等しいと見倣され、一つでも構成要素が非 NULL であって、且等しくない行同士は非等と見倣されます。それ以外その行の比較結果は未定 (NULL) です。 少なくとも一つの NULL があるすべての行の結果が非等もしくは NULL の場合、IN の結果は NULL となります。

6.15.4. NOT IN (scalar form)

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

NOT IN のこの形式の右側は丸括弧で括られたスカラー式のリストです。 左側の式の結果が右側の式のすべてと等しくない場合、結果は「真」です。 これは、次の表記法の簡略形です。

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

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

Tip: すべての場合に於いて x NOT IN yNOT (x IN y) と等価です。 もっとも、NULL 値については IN を使うときよりも NOT IN を使うときの方が初心者が間違いを犯す可能性がより高いようです。可能であれば条件を明確に表現することが最良です。

6.15.5. NOT IN (subquery form)

expression NOT IN (subquery)

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

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

EXISTS と同じように副問い合わせが最後まで評価されると思い込むのは賢くありません。

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

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

いつもの通り、式または副問い合わせの行にある NULL 値は、SQL の論理式の通常ルールで結合されます。 二つの行は対応するすべての構成要素が非 NULL で且等しい場合に等しいと見倣され、一つでも構成要素が非 NULL であって、且等しくない行同士は非等と見倣されます。それ以外その行の比較結果は未定 (NULL) です。 少なくとも一つの NULL があるすべての行の結果が非等もしくは NULL の場合、NOT IN の結果は NULL となります。

6.15.6. ANY/SOME

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

ANY のこの形式の右側は丸括弧で括られた副問い合わせで、正確に 1 列を返さなければなりません。左側の式は、与えられた 演算子を使っての副問い合わせの結果に評価、比較が行なわれ、論理値の結果を生成しなくてはなりません。 真の結果が得られていれば、ANY の結果は「真」となります。 (副問い合わせが行を返さない特別の場合を含め) 結果が真であるものが見つからない場合、結果は「偽」です。

SOMEANYに対する同義語です。IN= ANY と等価です。

成功しなかったか、少なくとも一つの右側の行が演算子の結果として NULL を生成した場合、ANY 構文の結果は偽ではなく NULL となることに注意してください。 これは、NULL 値の論理的な組合せに対する SQL の通常の取り決めに従うものです。

EXISTS と同じように副問い合わせが最後まで評価されると思い込むのは賢くありません。

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

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

いつもの通り、式または副問い合わせの行にある NULL 値は、SQL の論理式の通常ルールで結合されます。 二つの行は対応するすべての構成要素が非 NULL で且等しい場合に等しいと見倣され、一つでも構成要素が非 NULL であって、且等しくない行同士は非等と見倣されます。それ以外その行の比較結果は未定 (NULL) です。 少なくとも一つの NULL 行となった結果が存在すれば、ANY の結果は偽とはならず、真もしくは NULL となります。

6.15.7. ALL

expression operator ALL (subquery)

ALL のこの形式の右側は丸括弧で括られた副問い合わせで、正確に一つの列を返さなければなりません。左側の式は、与えられた 演算子を使っての副問い合わせの結果に評価、比較が行なわれ、論理値の結果を生成しなくてはなりません。 (副問い合わせが行を返さない特別の場合を含め) すべての行が真を返すのであれば ALL の結果は「真」となります。 偽の結果が見つかった場合、結果は「偽」です。

NOT IN<> ALLと同値です。

失敗はしなくても、少なくとも一つの右側の行が演算子の結果として NULL を生成した場合、ALL 構文の結果は真ではなく NULL となることに注意してください。 これは、NULL 値の論理的な組合せに対する SQL の通常の取り決めに従うものです。

EXISTS と同じように副問い合わせが最後まで評価されると思い込むのは賢くありません。

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

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

いつもの通り、式または副問い合わせの行にある NULL 値は、SQL の論理式の通常ルールで結合されます。 二つの行は対応するすべての構成要素が非 NULL で且等しい場合に等しいと見倣され、一つでも構成要素が非 NULL であって、且等しくない行同士は非等と見倣されます。それ以外その行の比較結果は未定 (NULL) です。 少なくとも一つの NULL 行となった結果が存在すれば、ALL の結果は真とはならず、偽もしくは NULL となります。

6.15.8. 行に関しての比較

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

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

いつもの通り、式または副問い合わせの行にある NULL 値は、SQL の論理式の通常ルールで結合されます。 二つの行は、対応するすべての構成要素が非 NULL で且等しい場合に等しいと見倣され、一つでも構成要素が非 NULL であって、且等しくない行同士は非等と見倣されます。 それ以外その行の比較結果は未定 (NULL) です。