行和数组比较

PostgreSQL 9.4.4 中文手册
上一页 | 上一级 | 章 9. 函数和操作符 | 下一页

# 9.23. 行和数组比较

本节描述几个特殊的构造，用于在多组值之间进行多重比较。 这些形式语法上和上一节的子查询形式相关，但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展； 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔值(真/假)。

## 9.23.1. `IN`

    expression IN (value [, ...])

右边是一个圆括弧包围的标量列表。如果左边的表达式结果等于任何右边表达式中的一个， 结果为"真"。它是下面这种方式的缩写

    expression = value1
    OR
    expression = value2
    OR
    ...

请注意，如果左边表达式的值为 NULL ，或者没有相等的右边值并且至少有一个右边表达式的值为 NULL ， 那么`IN`的结果将是 NULL ，而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。

## 9.23.2. `NOT IN`

    expression NOT IN (value [, ...])

右边是一个圆括弧包围的标量列表。如果左边的表达式结果不等于任何右边表达式，结果为"真"。 它是下面这种方式的缩写

    expression <> value1
    AND
    expression <> value2
    AND
    ...

请注意，如果左边表达式的值为 NULL ，或者没有相等的右边值并且至少有一个右边表达式的值为 NULL ， 那么`NOT IN`的结果将是 NULL ，而不是真。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。

> 提示: `x NOT IN y`在所有场合都等价于`NOT (x IN y)`。 但是，在处理 NULL 的时候，用`NOT IN`比用`IN`更容易迷惑新手。 最好用正逻辑来表达你的条件。

## 9.23.3. `ANY`/`SOME` (array)

    expression operator ANY (array expression)
    expression operator SOME (array expression)

右边是一个圆括弧包围的表达式，它必须生成一个数组值。左边表达式使用`operator` 对数组的每一个元素进行一次计算和比较，其结果必须是布尔值。如果至少获得一个真值， 则`ANY`结果为"真"。如果全部获得假值，则结果是"假" (包括数组不含任何元素的情况)。

如果数组表达式的值为 NULL ，那么`ANY`的结果也为 NULL 。 如果左边表达式的值为 NULL ，那么`ANY`的结果通常也为 NULL (某些不严格的比较操作符可能得到不同的结果)。另外， 如果右边的数组表达式中包含 NULL 元素并且没有为真的比较结果， 那么`ANY`的结果将是 NULL(某些不严格的比较操作符可能得到不同的结果)， 而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。

`SOME`是`ANY`的同意词。

## 9.23.4. `ALL` (array)

    expression operator ALL (array expression)

右边是一个圆括弧包围的表达式，它必须生成一个数组值。左边表达式使用`operator` 对数组的每一个元素进行一次计算和比较，其结果必须是布尔值。如果全部获得真值，`ALL` 结果为"真"(包括数组不含任何元素的情况)。如果至少获得一个假值，则结果是"假"。

如果数组表达式的值为 NULL ，那么`ALL`的结果也为 NULL 。 如果左边表达式的值为 NULL ，那么`ALL`的结果通常也为 NULL (某些不严格的比较操作符可能得到不同的结果)。另外， 如果右边的数组表达式中包含 NULL 元素并且没有为假的比较结果，那么`ALL` 的结果将是 NULL(某些不严格的比较操作符可能得到不同的结果)，而不是真。 这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。

## 9.23.5. 行构造器比较

    row_constructor operator row_constructor

两边都是一个第 4.2.13 节所述的行构造器； 两个行的字段数必须相同。两边都被计算并且逐行比较。目前，行构造器比较的 `operator`操作符仅允许为 `=`, `<>`, `<`, `<=`, `>`或`>=`。 每个行元素必须是有缺省B-tree操作符类的类型，否则尝试比较可能会产生错误。

> 注意: 如果比较使用较早的字段解决，那么与元素的数量或类型相关的错误可能不会发生。

`=`和`<>`与其它操作符稍有区别。如果两行对应的元素全都非空且相等， 那么这两行就被认为是相等的；如果两行对应的元素中有任意一对非空且不等， 那么这两行就被认为是不等的；否则这两行的比较结果是未知(NULL)。

对于 `<`, `<=`, `>`, `>=`操作符， 行中的元素将按照从左到右的顺序依次进行比较，直到遇见一对不相等的元素或者一对 NULL 值。 如果这对元素中存在至少一个 NULL 值，那么比较的结果是 NULL ； 否则这对元素的比较结果就是最终的比较结果。例如，`ROW(1,2,NULL) < ROW(1,3,0)` 的结果是真而不是 NULL ，因为比较到第二对元素的时候就已经得到了最终结果，不需要对第三对元素进行比较了。

> 注意: 在PostgreSQL 8.2之前，`<`, `<=`, `>`, `>=`并不遵守 SQL 标准。比如，`ROW(a,b) < ROW(c,d)` 将等价于`a < c AND b < d`，而正确的做法应当是等价于`a < c OR (a = c AND b < d)`。

    row_constructor IS DISTINCT FROM row_constructor

这个构造类似于`<>`行比较，但是它对 NULL 输入不生成 NULL ， 而是认为任何 NULL 都不等于任何非 NULL ，并且 NULL 之间是相等的。因此， 结果要么是真要么是假，而绝不会是未知(NULL)。

    row_constructor IS NOT DISTINCT FROM row_constructor

这个构造类似于`=`行比较，但是它对 NULL 输入不生成 NULL ， 而是认为任何 NULL 都不等于任何非 NULL ，并且 NULL 之间是相等的。 因此，结果要么是真要么是假，而绝不会是未知(NULL)。

## 9.23.6. 复合类型比较

    record operator record

如果结果依赖于比较两个NULL值或一个NULL值和一个非NULL值，SQL 规范要求逐行比较返回 NULL。 PostgreSQL仅当比较两个行构造的结果（就像第 9.23.5 节 中描述的那样）或一个行构造器和子查询的输出时这样做 (就像第 9.22 节描述的那样)。在其它情况下，两个复合类型的值进行比较， 认为两个NULL字段值是相等的，并且NULL大于非NULL。这是必要的，如此才能有一致的排序和复合类型的索引行为。

每一方都要评估并且它们是逐行比较的。仅在`operator` 是`=`、`<>`、`<`、`<=`、 `>`或`>=`，或具有相似语义的操作符时允许比较复合类型。 （具体来说，一个操作符可以是一个行比较操作符，如果它是B-tree操作符类的一员， 或者是B-tree操作符类`=`成员的否定。）以上操作符在行构造器上的缺省行为和 `IS [ NOT ] DISTINCT FROM`是相同的 （参阅第 9.23.5 节）。

为了支持包含没有缺省B-tree操作符类的元素的行匹配，为复合类型比较定义了下列操作符： `*=`、`*<>`、`*<`、`*<=`、 `*>`和`*>=`。这些操作符比较两行的内部二进制表示。 两行可能有不同的二进制表示，即使用等号操作符比较两行返回真。 这些比较操作符下的行排序是动态的，但是没什么意义。 这些操作符内部的用于物化视图，并且可能对于其他特殊用途， 比如替换有用，但是并不打算用于普通的写查询。

上一页 | 起始页 | 下一页
子查询表达式 | 上一级 | 返回集合的函数