UNION
、CASE
和相关结构 #SQL UNION
结构必须匹配可能不同的类型,才能成为一个单独的结果集。 解析算法分别应用于联合查询的每个输出列。INTERSECT
和 EXCEPT
结构以与 UNION
相同的方式解析不同的类型。 一些其他结构,包括 CASE
、ARRAY
、VALUES
以及 GREATEST
和 LEAST
函数,使用相同的算法来匹配其组件表达式并选择结果数据类型。
UNION
、CASE
和相关结构的类型解析
如果所有输入都是相同类型,并且不是 unknown
,则解析为该类型。
如果任何输入是域类型,则将其视为域的基础类型以进行后续步骤。[12]
如果所有输入都是 unknown
类型,则解析为 text
类型(字符串类别的首选类型)。 否则,为了剩余规则的目的,unknown
输入将被忽略。
如果非 unknown 输入不属于同一类型类别,则失败。
选择第一个非 unknown 输入类型作为候选类型,然后从左到右考虑每个其他非 unknown 输入类型。[13] 如果候选类型可以隐式转换为其他类型,但反之则不行,则选择其他类型作为新的候选类型。 然后继续考虑其余的输入。 如果在此过程的任何阶段选择了首选类型,则停止考虑其他输入。
将所有输入转换为最终的候选类型。 如果没有从给定输入类型到候选类型的隐式转换,则失败。
下面是一些示例。
示例 10.10. 联合中具有未指定类型的类型解析
SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows)
在这里,未知类型的字面量 'b'
将解析为 text
类型。
示例 10.11. 简单联合中的类型解析
SELECT 1.2 AS "numeric" UNION SELECT 1; numeric --------- 1 1.2 (2 rows)
字面量 1.2
的类型为 numeric
,而 integer
值 1
可以隐式转换为 numeric
,因此使用该类型。
示例 10.12. 转置联合中的类型解析
SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL); real ------ 1 2.2 (2 rows)
在这里,由于 real
类型不能隐式转换为 integer
,但是 integer
可以隐式转换为 real
,因此联合结果类型解析为 real
。
示例 10.13. 嵌套联合中的类型解析
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
操作也以成对方式解析。 但是,本节中描述的其他结构在一个解析步骤中考虑其所有输入。
如果您在文档中发现任何不正确、与特定功能的体验不符或需要进一步澄清的内容,请使用此表格报告文档问题。