相关文章推荐
博学的枇杷  ·  SQL中的嵌套CASE语句 - ·  2 月前    · 
唠叨的硬盘  ·  如何实现MySQL case when ...·  2 月前    · 
微笑的青蛙  ·  selenium ...·  1 月前    · 
帅呆的篮球  ·  子查詢 (SQL Server) - ...·  1 月前    · 
豪爽的热水瓶  ·  How to export a Hive ...·  3 周前    · 
慷慨大方的火腿肠  ·  C/C++ linux ...·  1 年前    · 
大气的稀饭  ·  ASP.NET ...·  2 年前    · 
精明的手术刀  ·  Problem with ...·  2 年前    · 

SQL UNION 结构必须使可能不相似的类型匹配成为一个单一的结果集。该决定算法被独立地应用到一个联合查询的每个输出列。 INTERSECT EXCEPT 采用和 UNION 相同的方法来决定不相似的类型。其他一些结构,包括 CASE ARRAY VALUES ,以及 GREATEST LEAST 函数,使用相同的算法来使它们的组成表达式匹配并选择一种结果数据类型。

UNION CASE 和相关结构的类型决定

  1. 如果所有的输入为相同类型,并且不是 unknown ,那么就决定是该类型。

  2. 如果任何输入是一种域类型,在所有后续步骤中都把它当做该域的基类型。

  3. 如果所有的输入为 unknown 类型,则决定为 text (字符串分类的首选类型)类型。否则,为了剩余规则, unknown 输入会被忽略。

  4. 如果非未知输入不全是相同的类型分类,则失败。

  5. 选择第一个非未知输入类型作为候选类型,然后从左到右考虑其他非未知输入类型。 如果候选类型可以隐式转换为其他类型,但反之不行,则选择其他类型作为新的候选类型。 然后继续考虑剩余的输入。 如果在此过程的任何阶段选择了首选类型,请停止考虑其他输入。

  6. 将所有输入转换为最终候选类型。如果没有从给定输入类型到候选类型的隐式转换,则失败。

示例1 联合中未指定类型的类型决定

    SELECT text 'a' AS "text" UNION SELECT 'b';
    ------
    (2 rows)

这里,未知类型文字 'b' 将被决定为类型 text

示例2 简单联合中的类型决定

    SELECT 1.2 AS "numeric" UNION SELECT 1;
     numeric
    ---------
    (2 rows)

文字 1.2 numeric 类型,且 integer 1 可以被隐式地造型为 numeric ,因此使用 numeric 类型。

示例3 可换位联合中的类型决定

    SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
    ------
    (2 rows)

这里,由于类型 real 被能被隐式地造型为 integer ,而 integer 可以被隐式地造型为 real ,联合结果类型被决定为 real

示例4 嵌套合并中的类型决定

    SELECT NULL UNION SELECT NULL UNION SELECT 1;
    ERROR:  UNION types text and integer cannot be matched

这个失败发生的原因是本数据库把多个 UNION 当作是成对操作的嵌套,也就是说上面的输入等同于:

    (SELECT NULL UNION SELECT NULL) UNION SELECT 1;

根据上面给定的规则,内层的 UNION 被确定为类型 text 。然后外层的 UNION 的输入是类型 text integer ,这就导致了上面看到的错误。通过确保最左边的 UNION 至少有一个输入类型为想要的结果类型,就可以修正这个问题。

INTERSECT EXCEPT 操作也被当作成对操作。不过,这一节中描述的其他结构会在一个决定步骤中考虑所有的输入。

多少有些类似于对待用于操作符和函数的域输入的方式,这种行为允许一种域类型能通过一个 UNION 或相似的结构保留下来, 只要用户小心地确保所有的输入都是(显式地或隐式地)准确类型。否则会使用该域的基类型。

出于历史原因, CASE 将其 ELSE 子句(如果有的话)视为“第一个”输入,之后再考虑 THEN 子句。在所有其他情况下,“从左到右”表示表达式在查询文本中出现的顺序。