Skip to content

9.2. 比较函数和运算符#

常见的比较运算符可用,如表 9.1所示。

表 9.1. 比较运算符

运算符说明
datatype < datatypeboolean小于
datatype > datatypeboolean大于
datatype <= datatypeboolean小于或等于
datatype >= datatypeboolean大于或等于
datatype = datatypeboolean等于
数据类型 <> 数据类型布尔值不等于
数据类型 != 数据类型布尔值不等于

注意

<>是“不等于”的标准 SQL 符号。!=是一个别名,在解析的非常早期阶段会被转换为<>。因此,不可能实现执行不同操作的!=<>运算符。

这些比较运算符可用于所有具有自然顺序的内置数据类型,包括数字、字符串和日期/时间类型。此外,如果数组、复合类型和范围的组件数据类型可比较,则可以比较它们。

通常也可以比较相关数据类型的值;例如integer``>``bigint会起作用。某些此类情况直接由“跨类型”比较运算符实现,但如果不存在此类运算符,解析器将强制将不太通用的类型转换为更通用的类型,并应用后者的比较运算符。

如上所示,所有比较运算符都是返回布尔值类型值的二元运算符。因此,诸如1 < 2 < 3之类的表达式无效(因为没有<运算符将布尔值与3进行比较)。使用下面所示的BETWEEN谓词来执行范围测试。

还有一些比较谓词,如表 9.2所示。这些谓词的行为与运算符非常相似,但具有 SQL 标准要求的特殊语法。

表 9.2. 比较谓词

谓词

说明

示例

数据类型 BETWEEN 数据类型 AND 数据类型布尔值

介于(包括范围端点)。

2 BETWEEN 1 AND 3t

2 BETWEEN 3 AND 1f

数据类型 NOT BETWEEN 数据类型 AND 数据类型布尔值

不介于(BETWEEN 的否定)。

2 NOT BETWEEN 1 AND 3f

数据类型 BETWEEN SYMMETRIC 数据类型 AND 数据类型布尔值

介于,在对两个端点值排序后。

2 BETWEEN SYMMETRIC 3 AND 1t

datatype NOT BETWEEN SYMMETRIC datatype AND datatypeboolean

在对两个端点值排序后,不介于两者之间。

2 NOT BETWEEN SYMMETRIC 3 AND 1f

datatype IS DISTINCT FROM datatypeboolean

不相等,将 null 视为可比较值。

1 IS DISTINCT FROM NULLt(而不是 NULL

NULL IS DISTINCT FROM NULLf(而不是 NULL

datatype IS NOT DISTINCT FROM datatypeboolean

相等,将 null 视为可比较值。

1 IS NOT DISTINCT FROM NULLf(而不是 NULL

NULL IS NOT DISTINCT FROM NULLt(而不是 NULL

datatype IS NULLboolean

测试值是否为 null。

1.5 IS NULLf

datatype IS NOT NULLboolean

测试值是否不为 null。

'null' IS NOT NULLt

datatype ISNULLboolean

测试值是否为 null(非标准语法)。

datatype NOTNULLboolean

测试值是否不为 null(非标准语法)。

boolean IS TRUEboolean

测试布尔表达式是否产生 true。

true IS TRUEt

NULL::boolean IS TRUEf(而不是 NULL

布尔值 IS NOT TRUE布尔值

测试布尔表达式是否产生假或未知。

true IS NOT TRUEf

NULL::boolean IS NOT TRUEt(而不是 NULL

布尔值 IS FALSE布尔值

测试布尔表达式是否产生假。

true IS FALSEf

NULL::boolean IS FALSEf(而不是 NULL

布尔值 IS NOT FALSE布尔值

测试布尔表达式是否产生真或未知。

true IS NOT FALSEt

NULL::boolean IS NOT FALSEt(而不是 NULL

布尔值 IS UNKNOWN布尔值

测试布尔表达式是否产生未知。

true IS UNKNOWNf

NULL::boolean IS UNKNOWNt(而不是 NULL

布尔值 IS NOT UNKNOWN布尔值

测试布尔表达式是否产生真或假。

true IS NOT UNKNOWNt

NULL::boolean IS NOT UNKNOWNf(而不是 NULL

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 NULLIS NOT NULL并不总是为行值表达式返回相反的结果;特别是,包含 null 和非 null 字段的行值表达式将对这两个测试都返回 false。在某些情况下,最好编写rowIS DISTINCT FROM NULLrow*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 UNKNOWNIS NOT UNKNOWN实际上与IS NULLIS NOT NULL相同,不同之处在于输入表达式必须为布尔类型。

还有一些与比较相关的函数可用,如表 9.3所示。

表 9.3. 比较函数

函数

说明

示例

num_nonnulls ( VARIADIC "any" ) → integer

返回非 null 参数的数量。

num_nonnulls(1, NULL, 2)2

num_nulls ( VARIADIC "any" ) → integer

返回 null 参数的数量。

num_nulls(1, NULL, 2)1