支援的版本:目前版本 (17) / 16 / 15 / 14 / 13
開發版本:devel
不支援的版本: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 / 7.1

10.5. UNIONCASE 及相關結構 #

SQL UNION 結構必須匹配可能不同的型別,才能成為單一結果集。解析演算法會分別應用於 union 查詢的每個輸出欄位。INTERSECTEXCEPT 結構以與 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)

常值 1.2 的型別為 numeric,而 integer1 可以隱式轉換為 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 具有至少一個所需結果型別的輸入來修正此問題。

INTERSECTEXCEPT 操作也以成對方式解析。但是,本節中描述的其他結構會在一個解析步驟中考量其所有輸入。




[12] 有點像是針對運算子和函數的網域輸入處理方式,只要使用者小心確保所有輸入都隱式或顯式地屬於該確切型別,此行為就可以讓網域型別透過 UNION 或類似的結構來保留。否則,將使用網域的基礎型別。

[13] 由於歷史原因,CASE 將其 ELSE 子句(如果有的話)視為「第一個」輸入,之後才會考量 THEN 子句。在所有其他情況下,「從左到右」表示表示式在查詢文字中出現的順序。

提交更正

如果您在文件中發現任何不正確、與您使用特定功能的經驗不符,或需要進一步說明的內容,請使用此表單回報文件問題。