UNION
, CASE
, 以及相关构造 #SQL UNION
构造必须将可能不相同的类型匹配起来,才能成为一个单一的结果集。匹配算法会单独应用于 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)
此处,未知类型字面量 '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
操作也以成对的方式解析。但是,本节中描述的其他构造在一个解析步骤中考虑所有输入。
如果您在文档中发现任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。