↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 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 / 7.1
历史版本。 PostgreSQL 11 已结束支持。 2023-11-09. 请参阅 当前版本手册.

10.5. UNION、CASE 及相关结构 #

SQL 的 UNION 结构必须让可能不同的类型彼此匹配,以形成单一结果集。该解析算法会分别应用到联合查询的每个输出列。INTERSECT 和 EXCEPT 结构以与 UNION 相同的方式解析不同类型。其他一些结构,包括 CASE、ARRAY、VALUES 以及 GREATEST 和 LEAST 函数,也使用完全相同的算法来匹配其组成表达式并选择结果数据类型。

UNION、CASE 及相关结构的类型解析

  1. 如果所有输入都是同一类型,且该类型不是 unknown,就解析为该类型。

  2. 如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基础类型。[11]

  3. 如果所有输入都是 unknown 类型,则解析为 text 类型(字符串分类的首选类型)。否则,在剩余规则中忽略 unknown 输入。

  4. 如果非 unknown 输入并非全都属于同一类型分类,则失败。

  5. 选择第一个非 unknown 输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非 unknown 输入类型。[12] 如果候选类型可以隐式转换为另一类型,而反过来不行,则把另一类型选为新的候选类型。然后继续考虑剩余输入。如果在此过程的任何阶段选中了首选类型,就停止继续考虑其他输入。

  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,而 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 至少有一个输入属于期望的结果类型。

INTERSECT 和 EXCEPT 也同样按成对方式解析。不过,本节介绍的其他结构会在一次解析步骤中同时考虑它们的所有输入。




[11] 这在某种程度上类似于操作符和函数对域输入的处理方式;只要用户确保所有输入都隐式或显式地正好属于该域类型,这种行为就能让域类型在 UNION 或类似结构中得以保留。否则,就会使用该域的基础类型。

[12] 出于历史原因,CASE 会把其 ELSE 子句(如果有)视为“第一个”输入,THEN 子句则在其后考虑。其他所有情况中,“从左到右”都指表达式在查询文本中出现的顺序。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.