UNION、CASE及相关结构 #SQL 的UNION结构必须让可能不同的类型彼此匹配,以形成单一结果集。该解析算法会分别应用到联合查询的每个输出列。INTERSECT和EXCEPT结构以与UNION相同的方式解析不同类型。其他一些结构,包括CASE、ARRAY、VALUES以及GREATEST和LEAST函数,也使用完全相同的算法来匹配其组成表达式并选择结果数据类型。
UNION、CASE及相关结构的类型解析
如果所有输入都是同一类型,且该类型不是unknown,就解析为该类型。
如果任何输入是域类型,则在后续所有步骤中都把它当作该域的基类型。 [12]
如果所有输入都是unknown类型,则解析为text类型(字符串分类的首选类型)。否则,在剩余规则中忽略unknown输入。
如果非unknown输入并非全都属于同一类型分类,则失败。
选择第一个非unknown输入的类型作为候选类型,然后按从左到右的顺序考虑其余每个非unknown输入类型。 [13] 如果候选类型可以隐式转换为另一类型,而反过来不行,则把另一类型选为新的候选类型。然后继续考虑剩余输入。如果在此过程的任何阶段选中了首选类型,就停止继续考虑其他输入。
把所有输入都转换为最终候选类型。如果某个输入类型到候选类型不存在隐式转换,则失败。
下面是一些示例。
Example 10.10. UNION 中未充分指定类型时的类型解析
SELECT text 'a' AS "text" UNION SELECT 'b'; text ------ a b (2 rows)
这里,unknown类型文字'b'会被解析为text类型。
Example 10.11. 简单 UNION 中的类型解析
SELECT 1.2 AS "numeric" UNION SELECT 1;
numeric
---------
1
1.2
(2 rows)
文字常量1.2的类型是numeric,而integer值1可以隐式转换为numeric,因此使用该类型。
Example 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。
Example 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也同样按成对方式解析。不过,本节介绍的其他结构会在一次解析步骤中同时考虑它们的所有输入。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。