代码之家  ›  专栏  ›  技术社区  ›  deinspanjer

在SQL或PostgreSQL规范中,什么解释了数组与原语的比较?

  •  2
  • deinspanjer  · 技术社区  · 6 年前

    我想知道为什么可以在数组内部将空值精确地比较为相等,但不能比较为基元。

    例如,下面的查询演示了:

    SELECT NULL = NULL AS does_not_equal
         , NULL::bool = NULL::bool AS does_equal
         , NULL::int =  NULL::int AS does_equal
         , NULL::text = NULL::text AS does_equal
         , ARRAY[NULL] = ARRAY[NULL] AS does_equal
         , ARRAY[NULL]::bool[] = ARRAY[NULL]::bool[] AS does_equal
         , ARRAY[NULL]::int[] = ARRAY[NULL]::int[] AS does_equal
         , ARRAY[NULL]::text[] = ARRAY[NULL]::text[] AS does_equal
    ;
    

    我理解为什么原语的空=空是空的,我还认为我理解为什么比较复合类型会对两边都为空的字段给出一个真正的比较,主要是因为*=运算符查看类型的二进制值。但是数组似乎没有使用*=操作符,而且到目前为止,我在搜索中还没有找到任何解释。

    2 回复  |  直到 6 年前
        1
  •  0
  •   Laurenz Albe    6 年前

    这是一个复杂的故事。

    以下是SQL标准(ISO/IEC 9075-2)在“8.2”节中所说的内容 <比较谓词“:

    十五 YV 是两个值,由<值表达式>s表示 X Y ,分别。结果:

    X <comp op> Y

    确定如下:
    案例:

    1. 如果任一 十五 YV 是空值,然后

      X COMP公司; Y

      是未知的。

    2. 否则,

      案例:

      1. 如果声明的类型 十五 YV 行类型是否具有度数? n 然后让 X ,1(一)个 艾斯 n , 表示值表达式,其值和声明类型是 第四域 十五 和 让 Y 表示值表达式,其值和声明类型是 第四域 YV .
        结果

        X COMP公司; Y

        确定如下:

        1. X = Y 当且仅当 X = Y 为了所有 .
        2. X &; Y 当且仅当 X = Y 为了所有 &; n X n = Y n 对于一些 n .
        3. X = Y 如果没有,只有当没有( X = Y 对于一些 .
        4. X &; Y 当且仅当 X = Y Y &; X .
        5. X COMP公司; Y 未知 如果 X COMP公司; Y 既不是 也不 .
      2. 如果声明的类型 十五 YV 数组类型是否具有基数 N1 N2 分别 然后让 X ,1(一)个 艾斯 N1 ,表示值表达式,其值和声明的类型为 的 第四元素 十五 Y 表示值表达式,其值和声明的类型为 是这样的吗? 第四元素 YV . 结果

        X COMP公司; Y

        确定如下:

        1. X = Y 如果 N1 = 0(零)和 N2 = 0(零)。
        2. X = Y 如果 N1 = N2 而且,为了所有 , X = Y .
        3. X = Y 当且仅当 N1 阿西 N2 与否 X = Y 对一些人来说 .
        4. X COMP公司; Y 未知 如果 X COMP公司; Y 既不是 也不 .

    这非常令人困惑,例如,我没有看到规范hoz wo将数组与除相等运算符之外的其他运算符进行比较。

    该标准有时也会自相矛盾。

    这个 *= 运算符只存在于 record ,不适用于数组。它的作用与 = ,但更有效,因为如果其长度不同,它不会“绕行”值。

    最好是接受语义。

    PostgreSQL似乎没有遵循这个标准。

    空本身就是令人困惑的,复合或数组中的空更是如此。

        2
  •  0
  •   Gordon Linoff    6 年前

    我找不到你描述的行为的文档。然而, NULL 对于记录和行构造函数,s被认为是相等的,并对此进行了明确说明:

    SQL规范要求按行进行比较,以便在以下情况下返回空值: 结果取决于比较两个空值或一个空值和一个 非空。…。在其他情况下,其中两个复合类型值是 相比之下,两个空字段值被认为是相等的,而一个空字段值是 大于非空值。

    数组不是复合类型。似乎也在使用类似的逻辑。