10.5. UNION,CASE 和相关构造
SQL UNION
构造必须匹配可能不同的类型才能成为单个结果集。解析算法分别应用于联合查询的每个输出列。 INTERSECT
和EXCEPT
构造以与UNION
相同的方式解析不同的类型。 CASE
,ARRAY
,VALUES
,GREATEST
和LEAST
构造使用相同的算法来匹配其组件表达式并选择结果数据类型。
UNION
,CASE
和相关构造的类型解析
-
如果所有 Importing 均为同一类型,而不是
unknown
,则解析为该类型。 -
如果任何 Importing 属于域类型,则在所有后续步骤中都将其视为域的基本类型。 [11]
-
如果所有 Importing 均为
unknown
类型,则解析为text
类型(字符串类别的首选类型)。否则,出于其余规则的目的,将忽略unknown
Importing。 -
如果未知 Importing 不是所有相同类型类别,则失败。
-
如果存在第一个未知 Importing 类型,则选择该类别中的首选类型。
-
否则,请选择最后一个未知 Importing 类型,该类型允许将所有先前的未知 Importing 隐式转换为该类型。 (总是存在这种类型,因为至少列表中的第一个类型必须满足此条件.)
-
将所有 Importing 转换为所选类型。如果没有从给定 Importing 到所选类型的转换,则失败。
以下是一些示例。
示例 10.10. union 中类型未指定的类型解析
SELECT text 'a' AS "text" UNION SELECT 'b';
text
------
a
b
(2 rows)
在这里,未知类型的 Literals'b'
将解析为text
。
示例 10.11. 简单联合中的类型解析
SELECT 1.2 AS "numeric" UNION SELECT 1;
numeric
---------
1
1.2
(2 rows)
Literals1.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
视为成对操作的嵌套。也就是说,此 Importing 与
(SELECT NULL UNION SELECT NULL) UNION SELECT 1;
根据上面给出的规则,内部UNION
被解析为运行类型text
。然后,外部UNION
具有类型text
和integer
的 Importing,从而导致观察到的错误。可以通过确保最左边的UNION
具有期望结果类型的至少一个 Importing 来解决该问题。
INTERSECT
和EXCEPT
操作同样成对解决。但是,本节中描述的其他构造会在一个解析步骤中考虑所有 Importing。
[11]有点像对运算符和函数的域 Importing 的处理,这种行为允许通过UNION
或类似的结构保留域类型,只要用户注意确保所有 Importing 都隐式或显式属于该确切类型。否则,将首选域的基本类型。