PostgreSQL 9.4.4 中文手册 | |||
---|---|---|---|
上一页 | 上一级 | 章 9. 函数和操作符 | 下一页 |
本节描述几个特殊的构造,用于在多组值之间进行多重比较。 这些形式语法上和上一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔值(真/假)。
expression IN (value [, ...])
右边是一个圆括弧包围的标量列表。如果左边的表达式结果等于任何右边表达式中的一个, 结果为"真"。它是下面这种方式的缩写
expression = value1 OR expression = value2 OR ...
请注意,如果左边表达式的值为 NULL ,或者没有相等的右边值并且至少有一个右边表达式的值为 NULL , 那么IN的结果将是 NULL ,而不是假。这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。
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更容易迷惑新手。 最好用正逻辑来表达你的条件。
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的同意词。
expression operator ALL (array expression)
右边是一个圆括弧包围的表达式,它必须生成一个数组值。左边表达式使用operator 对数组的每一个元素进行一次计算和比较,其结果必须是布尔值。如果全部获得真值,ALL 结果为"真"(包括数组不含任何元素的情况)。如果至少获得一个假值,则结果是"假"。
如果数组表达式的值为 NULL ,那么ALL的结果也为 NULL 。 如果左边表达式的值为 NULL ,那么ALL的结果通常也为 NULL (某些不严格的比较操作符可能得到不同的结果)。另外, 如果右边的数组表达式中包含 NULL 元素并且没有为假的比较结果,那么ALL 的结果将是 NULL(某些不严格的比较操作符可能得到不同的结果),而不是真。 这个行为遵照 SQL 处理布尔值和 NULL 组合时的规则。
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)。
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操作符类的元素的行匹配,为复合类型比较定义了下列操作符: *=、*<>、*<、*<=、 *>和*>=。这些操作符比较两行的内部二进制表示。 两行可能有不同的二进制表示,即使用等号操作符比较两行返回真。 这些比较操作符下的行排序是动态的,但是没什么意义。 这些操作符内部的用于物化视图,并且可能对于其他特殊用途, 比如替换有用,但是并不打算用于普通的写查询。