他のバージョンの文書 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

10.5. UNIONCASEおよび関連する構文

UNION SQL構文は、似ていない可能性がある型を1つの検索結果になるように適合させなければなりません。 解決アルゴリズムは1つのunion問い合わせの出力列ごとに適用されます。 INTERSECT構文とEXCEPT構文は、UNIONと同じ方法で、似ていない可能性がある型の解決を行います。 CASEARRAYVALUESを含むいくつかの構文とGREATESTLEAST関数は同一のアルゴリズムを使用して、その要素式を適合させ、結果のデータ型を選択します。

UNIONCASEおよび関連する構文の型解決

  1. もし全ての入力値が同一型であり、unknownではない場合、その型として解決されます。

  2. 入力のいずれかがドメイン型であれば、以降の段階すべてでドメインの基本型であるかのように扱います。 [12]

  3. もし全ての入力値がunknown型だった場合、text型(文字列カテゴリの優先される型)として解決されます。 そうでない場合はunknown入力は残りの規則のために無視されます。

  4. もしunknownではない入力値が全て同じ型カテゴリでなければ失敗します。

  5. 最初のunknownではない入力データ型を候補の型として選択します。 それから、他のunknownではない入力データ型をそれぞれ左から右へ考慮します。 [13] 候補の型が暗黙的にある別の型に変換できるが、その逆はできない場合、その別の型を新しい候補の型として選択します。 それから残りの入力の考慮を続けます。 この処理のある段階で、優先される型が選択されれば、追加の入力の考慮を止めます。

  6. 入力値をすべて最終的な候補の型に変換します。 指定された入力型から候補の型への暗黙の変換が存在しない場合は失敗します。

以下に例を示します。

例10.10 Unionにおける指定された型の型解決

SELECT text 'a' AS "text" UNION SELECT 'b';

 text
------
 a
 b
(2 rows)

ここで、unknown型のリテラル'b'textへと解決されます。


例10.11 簡単なUnionにおける型解決

SELECT 1.2 AS "numeric" UNION SELECT 1;

 numeric
---------
       1
     1.2
(2 rows)

numeric型のリテラル1.2integer型の値1は、暗黙的にnumericにキャスト可能です。 したがって、この型が使用されます。


例10.12 転置されたUNIONにおける型解決

SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);

 real
------
    1
  2.2
(2 rows)

ここで、real型を暗黙的にinteger型にキャストすることはできませんが、integer型を暗黙的にreal型にキャストすることはできるため、UNIONの結果データ型はreal型として解決されます。


例10.13 入れ子のUNIONにおける型解決

SELECT NULL UNION SELECT NULL UNION SELECT 1;

ERROR:  UNION types text and integer cannot be matched

この失敗は、PostgreSQLが複数のUNIONを二項演算の入れ子として扱うために起こります。すなわち、この入力は以下と同じです。

(SELECT NULL UNION SELECT NULL) UNION SELECT 1;

内側のUNIONは、上に挙げた規則に従って、型textになるものとして解決されます。 すると、外側のUNIONは型textintegerの入力を受け取ることになりますので、上のようなエラーになります。 一番左のUNIONが望む結果型の入力を少なくとも1つ確実に受け取るようにすることで、この問題を修正できます。

INTERSECTEXCEPT操作は同様に二項演算として解決されます。 しかしながら、この節のその他の構文は入力をすべて解決の段階1つで考慮します。




[12] 演算子や関数に対するドメイン入力の取り扱いとある程度似ていて、この振舞いにより、利用者が注意して入力をすべて厳密な型であると明示的にもしくは暗黙的に保証する限り、ドメイン型をUNIONや類似の構成体に保存できます。 そうでなければ、ドメインの基本型が使われます。

[13] 歴史的な理由により、CASEは(もしあれば)そのELSE句を最初の入力として扱い、THEN句はその後で考慮します。 それ以外の場合では左から右は問い合わせテキスト内で式が現れる順を意味します。