9.2. 比较函数和运算符#
常见的比较运算符可用,如表 9.1所示。
表 9.1. 比较运算符
运算符 | 说明 |
---|---|
datatype < datatype → boolean | 小于 |
datatype > datatype → boolean | 大于 |
datatype <= datatype → boolean | 小于或等于 |
datatype >= datatype → boolean | 大于或等于 |
datatype = datatype → boolean | 等于 |
数据类型 <> 数据类型 → 布尔值 | 不等于 |
数据类型 != 数据类型 → 布尔值 | 不等于 |
注意
<>
是“不等于”的标准 SQL 符号。!=
是一个别名,在解析的非常早期阶段会被转换为<>
。因此,不可能实现执行不同操作的!=
和<>
运算符。
这些比较运算符可用于所有具有自然顺序的内置数据类型,包括数字、字符串和日期/时间类型。此外,如果数组、复合类型和范围的组件数据类型可比较,则可以比较它们。
通常也可以比较相关数据类型的值;例如integer``>``bigint
会起作用。某些此类情况直接由“跨类型”比较运算符实现,但如果不存在此类运算符,解析器将强制将不太通用的类型转换为更通用的类型,并应用后者的比较运算符。
如上所示,所有比较运算符都是返回布尔值
类型值的二元运算符。因此,诸如1 < 2 < 3
之类的表达式无效(因为没有<
运算符将布尔值与3
进行比较)。使用下面所示的BETWEEN
谓词来执行范围测试。
还有一些比较谓词,如表 9.2所示。这些谓词的行为与运算符非常相似,但具有 SQL 标准要求的特殊语法。
表 9.2. 比较谓词
谓词 说明 示例 |
---|
介于(包括范围端点)。
|
不介于(
|
介于,在对两个端点值排序后。
|
在对两个端点值排序后,不介于两者之间。
|
不相等,将 null 视为可比较值。
|
相等,将 null 视为可比较值。
|
测试值是否为 null。
|
测试值是否不为 null。
|
测试值是否为 null(非标准语法)。 |
测试值是否不为 null(非标准语法)。 |
测试布尔表达式是否产生 true。
|
测试布尔表达式是否产生假或未知。
|
测试布尔表达式是否产生假。
|
测试布尔表达式是否产生真或未知。
|
测试布尔表达式是否产生未知。
|
测试布尔表达式是否产生真或假。
|
BETWEEN
谓词简化了范围测试
a BETWEEN x AND y
等同于
a >= x AND a <= y
请注意,BETWEEN
将端点值视为包含在范围内。BETWEEN SYMMETRIC
类似于BETWEEN
,但没有要求AND
左侧的参数小于或等于右侧的参数。如果不是,则自动交换这两个参数,以便始终暗示非空范围。
BETWEEN
的各种变体是根据普通比较运算符实现的,因此适用于任何可以比较的数据类型。
注意
在BETWEEN
语法中使用AND
会与将AND
用作逻辑运算符产生歧义。为了解决此问题,只允许有限的一组表达式类型作为BETWEEN
子句的第二个参数。如果您需要在BETWEEN
中编写更复杂的子表达式,请在子表达式周围加上括号。
当任一输入为 null 时,普通比较运算符产生 null(表示““未知””),而不是 true 或 false。例如,7 = NULL
产生 null,7 <> NULL
也是如此。当此行为不合适时,请使用IS [NOT] DISTINCT FROM
谓词
a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b
对于非 null 输入,IS DISTINCT FROM
与<>
运算符相同。但是,如果两个输入均为 null,则返回 false,如果仅一个输入为 null,则返回 true。类似地,IS NOT DISTINCT FROM
对于非 null 输入与=
相同,但当两个输入均为 null 时返回 true,当仅一个输入为 null 时返回 false。因此,这些谓词有效地起作用,就好像 null 是一个普通数据值,而不是““未知””。
要检查值是否为 null,请使用谓词
expression IS NULL
expression IS NOT NULL
或等效但非标准的谓词
expression ISNULL
expression NOTNULL
不要编写*
expression*= NULL
,因为NULL
不““等于””NULL
。(null 值表示未知值,并且不知道两个未知值是否相等。)
提示
某些应用程序可能期望,如果*expression
*求值为 null 值,则*
expression*= NULL
返回 true。强烈建议修改这些应用程序以符合 SQL 标准。但是,如果无法做到这一点,则可以使用transform_null_equals配置变量。如果启用它,PostgreSQL将把x = NULL
子句转换为x IS NULL
。
如果*expression
是行值,则当行表达式本身为 null 或行中的所有字段都为 null 时,IS NULL
为 true,而当行表达式本身为非 null 且行中的所有字段都为非 null 时,IS NOT NULL
为 true。由于此行为,IS NULL
和IS NOT NULL
并不总是为行值表达式返回相反的结果;特别是,包含 null 和非 null 字段的行值表达式将对这两个测试都返回 false。在某些情况下,最好编写row
IS DISTINCT FROM NULL
或row
*IS NOT DISTINCT FROM NULL
,它将简单地检查总体行值是否为 null,而不会对行字段进行任何其他测试。
布尔值也可以使用谓词进行测试
boolean_expression IS TRUE
boolean_expression IS NOT TRUE
boolean_expression IS FALSE
boolean_expression IS NOT FALSE
boolean_expression IS UNKNOWN
boolean_expression IS NOT UNKNOWN
这些函数始终返回 true 或 false,绝不会返回 null 值,即使操作数为 null 也是如此。null 输入被视为逻辑值“未知”。请注意,IS UNKNOWN
和IS NOT UNKNOWN
实际上与IS NULL
和IS NOT NULL
相同,不同之处在于输入表达式必须为布尔类型。
还有一些与比较相关的函数可用,如表 9.3所示。
表 9.3. 比较函数
函数 说明 示例 |
---|
返回非 null 参数的数量。
|
返回 null 参数的数量。
|