PostgreSQL 行和数组比较
- 9.24.1.
IN
- 9.24.2.
NOT IN
- 9.24.3.
ANY
/SOME
(array) - 9.24.4.
ALL
(array) - 9.24.5. 行构造器比较
- 9.24.6. 组合类型比较
本节描述几个特殊的结构,用于在值的组之间进行多重比较。这些形式语法上和前面一节的子查询形式相关,但是不涉及子查询。 这种形式涉及的数组子表达式是PostgreSQL的扩展; 其它的是SQL兼容的。所有本节记录的表达式形式都返回布尔(Boolean)结果(真/假)。
9.24.1. IN
expression
IN (value
[, ...])
右手边是一个圆括弧包围的标量列表。如果左手边表达式的结果等于任何右手边表达式中的一个,结果为“真”。它是下面形式的缩写
expression
= value1
OR
expression
= value2
OR
...
请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么IN
结构的结果将为空值,而不是假。这符合 SQL 处理空值的布尔组合的一般规则。
9.24.2. NOT IN
expression
NOT IN (value
[, ...])
右手边是一个圆括弧包围的标量列表。如果左手边表达式的结果不等于所有右手边表达式,结果为“真”。它是下面形式的缩写
expression
<> value1
AND
expression
<> value2
AND
...
请注意如果左手边表达式得到空值,或者没有相等的右手边值并且至少有一个右手边的表达式得到空值,那么NOT IN
结构的结果将为空值, 而不是我们可能天真地认为的真值。这符合 SQL 处理空值的布尔组合的一般规则。
提示
x NOT IN y
在所有情况下都等效于NOT (x IN y)
。但是,在处理空值的时候,用NOT IN
比用IN
更可能迷惑新手。最好尽可能用正逻辑来表达你的条件。
9.24.3. ANY
/SOME
(array)
expression
operator
ANY (array expression
)
expression
operator
SOME (array expression
)
右手边是一个圆括弧包围的表达式,它必须得到一个数组值。左手边表达式被计算并且使用给出的操作符
对数组的每个元素进行比较,这个操作符必须得到布尔结果。如果得到了任何真值结果,那么ANY
的结果是“真”。 如果没有找到真值结果(包括数组只有零个元素的情况),那么结果是
“假”。
如果数组表达式得到一个空数组,ANY
的结果将为空值。如果左手边的表达式得到空值,ANY
通常是空值(尽管一个非严格比较操作符可能得到一个不同的结果)。另外,如果右手边的数组包含任何空值元素或者没有得到真值比较结果,ANY
的结果将是空值而不是假(再次,假设是一个严格的比较操作符)。这符合 SQL 对空值的布尔组合的一般规则。
SOME
是ANY
的同义词。
9.24.4. ALL
(array)
expression
operator
ALL (array expression
)
右手边是一个圆括弧包围的表达式,它必须得到一个数组值。左手边表达式将被计算并使用给出的操作符
与数组的每个元素进行比较,这个操作符必须得到一个布尔结果。如果所有比较都得到真值结果,那么ALL
的结果是 “真”(包括数组只有零个元素的情况)。如果有任何假值结果,那么结果是
“假”。
如果数组表达式得到一个空数组,ALL
的结果将为空值。如果左手边的表达式得到空值,ALL
通常是空值(尽管一个非严格比较操作符可能得到一个不同的结果)。另外,如果右手边的数组包含任何空值元素或者没有得到假值比较结果,ALL
的结果将是空值而不是真(再次,假设是一个严格的比较操作符)。这符合 SQL 对空值的布尔组合的一般规则。
9.24.5. 行构造器比较
row_constructor
operator
row_constructor
每一边都是一个行构造器,如第 4.2.13 节所述。两个行值必须具有相同数量的域。每一边被计算并且被逐行比较。当操作符
是 =
、
<>
、 <
<=
、 >
、 >=
时,允许进行行构造器比较。每一个行元素必须是具有一个默认 B 树操作符类的类型,否则尝试比较会产生一个错误。
注意
Errors related to the number or types of elements might not occur if the comparison is resolved using earlier columns.
=
和<>
情况略有不同。如果两行的所有对应成员都是非空且相等则这两行被认为相等;如果任何对应成员是非空但是不相等则这两行不相等;否则行比较的结果为未知(空值)。
对于<
、<=
、>
和>=
情况,行元素被从左至右比较,在找到一处不等的或为空的元素对就立刻停下来。如果这一对元素都为空值,则行比较的结果为未知(空值);否则这一对元素的比较结果决定行比较的结果。例如,ROW(1,2,NULL) < ROW(1,3,0)
得到真,而不是空值,因为第三对元素并没有被考虑。
注意
在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
这个结构与<>
行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。
row_constructor
IS NOT DISTINCT FROM row_constructor
这个结构与=
行比较相似,但是它对于空值输入不会得到空值。任何空值被认为和任何非空值不相等(有区别),并且任意两个空值被认为相等(无区别)。因此结果将总是为真或为假,永远不会是空值。
9.24.6. 组合类型比较
record
operator
record
SQL 规范要求在结果依赖于比较两个 NULL 值或者一个 NULL 与一个非 NULL 时逐行比较返回 NULL。PostgreSQL只有在比较两个行构造器(如第 9.24.5 节)的结果或者比较一个行构造器与一个子查询的输出时才这样做(如 第 9.23 节中所述)。在其他比较两个组合类型值的环境中,两个 NULL 域值被认为相等,并且一个 NULL 被认为大于一个非 NULL。为了得到组合类型的一致的排序和索引行为,这样做是必要的。
每一边都会被计算并且它们会被逐行比较。当操作符
是 =
、 <>
、 <
、 <=
、 >
或者 >=
时或者具有与这些类似的语义时,允许组合类型的比较(更准确地说,如果一个操作符是一个
B 树操作符类的成员,或者是一个 B 树操作符类的=
成员的否定词,它就可以是一个行比较操作符)。 上述操作符的行为与用于行构造器(见第 9.24.5 节)的IS [ NOT ] DISTINCT FROM
相同。
为了支持包含无默认 B 树操作符类的元素的行匹配,为组合类型比较定义了下列操作符: *=
、 *<>
、 *<
、 *<=
、 *>
以及 *>=
。
这些操作符比较两行的内部二进制表达。即使两行用相等操作符的比较为真,两行也可能具有不同的二进制表达。 行在这些比较操作符之下的排序是决定性的,其他倒没什么意义。 这些操作符在内部被用于物化视图并且可能对其他如复制和B-树复制(参见 第 63.4.2 节)之类的特殊功能有用,但是它们并不打算用在书写查询这类普通用途中。