UNION
、CASE
および関連する構文 #
UNION
SQL構文は、似ていない可能性がある型を1つの検索結果になるように適合させなければなりません。
解決アルゴリズムは1つのunion問い合わせの出力列ごとに適用されます。
INTERSECT
構文とEXCEPT
構文は、UNION
と同じ方法で、似ていない可能性がある型の解決を行います。
CASE
、ARRAY
、VALUES
を含むいくつかの構文とGREATEST
、LEAST
関数は同一のアルゴリズムを使用して、その要素式を適合させ、結果のデータ型を選択します。
UNION
、CASE
および関連する構文の型解決
もし全ての入力値が同一型であり、unknown
ではない場合、その型として解決されます。
入力のいずれかがドメイン型であれば、以降の段階すべてでドメインの基本型であるかのように扱います。 [12]
もし全ての入力値がunknown
型だった場合、text
型(文字列カテゴリの優先される型)として解決されます。
そうでない場合、unknown
入力は残りの規則のために無視されます。
もしunknownではない入力値が全て同じ型カテゴリでなければ失敗します。
最初のunknownではない入力データ型を候補の型として選択します。 それから、他のunknownではない入力データ型をそれぞれ左から右へ考慮します。 [13] 候補の型が暗黙的にある別の型に変換できるが、その逆はできない場合、その別の型を新しい候補の型として選択します。 それから残りの入力の考慮を続けます。 この処理のある段階で、優先される型が選択されれば、追加の入力の考慮を止めます。
入力値をすべて最終的な候補の型に変換します。 指定された入力型から候補の型への暗黙の変換が存在しない場合は失敗します。
以下に例を示します。
例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.2
とinteger
型の値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
は型text
とinteger
の入力を受け取ることになりますので、上のようなエラーになります。
一番左のUNION
が望む結果型の入力を少なくとも1つ確実に受け取るようにすることで、この問題を修正できます。
INTERSECT
とEXCEPT
操作は同様に二項演算として解決されます。
しかしながら、この節のその他の構文は入力をすべて解決の段階の1つで考慮します。