Skip to content

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. 比较谓词

谓词

说明

示例

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

介于(包括范围端点)。

2 BETWEEN 1 AND 3 → t

2 BETWEEN 3 AND 1 → f

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

不介于(BETWEEN 的否定)。

2 NOT BETWEEN 1 AND 3 → f

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

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

2 BETWEEN SYMMETRIC 3 AND 1 → t

datatype NOT BETWEEN SYMMETRIC datatype AND datatype → boolean

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

2 NOT BETWEEN SYMMETRIC 3 AND 1 → f

datatype IS DISTINCT FROM datatype → boolean

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

1 IS DISTINCT FROM NULL → t(而不是 NULL)

NULL IS DISTINCT FROM NULL → f(而不是 NULL)

datatype IS NOT DISTINCT FROM datatype → boolean

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

1 IS NOT DISTINCT FROM NULL → f(而不是 NULL)

NULL IS NOT DISTINCT FROM NULL → t(而不是 NULL)

datatype IS NULL → boolean

测试值是否为 null。

1.5 IS NULL → f

datatype IS NOT NULL → boolean

测试值是否不为 null。

'null' IS NOT NULL → t

datatype ISNULL → boolean

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

datatype NOTNULL → boolean

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

boolean IS TRUE → boolean

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

true IS TRUE → t

NULL::boolean IS TRUE → f(而不是 NULL)

布尔值 IS NOT TRUE → 布尔值

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

true IS NOT TRUE → f

NULL::boolean IS NOT TRUE → t(而不是 NULL)

布尔值 IS FALSE → 布尔值

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

true IS FALSE → f

NULL::boolean IS FALSE → f(而不是 NULL)

布尔值 IS NOT FALSE → 布尔值

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

true IS NOT FALSE → t

NULL::boolean IS NOT FALSE → t(而不是 NULL)

布尔值 IS UNKNOWN → 布尔值

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

true IS UNKNOWN → f

NULL::boolean IS UNKNOWN → t(而不是 NULL)

布尔值 IS NOT UNKNOWN → 布尔值

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

true IS NOT UNKNOWN → t

NULL::boolean IS NOT UNKNOWN → f(而不是 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 NULL和IS NOT NULL并不总是为行值表达式返回相反的结果;特别是,包含 null 和非 null 字段的行值表达式将对这两个测试都返回 false。在某些情况下,最好编写rowIS 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. 比较函数

函数

说明

示例

num_nonnulls ( VARIADIC "any" ) → integer

返回非 null 参数的数量。

num_nonnulls(1, NULL, 2) → 2

num_nulls ( VARIADIC "any" ) → integer

返回 null 参数的数量。

num_nulls(1, NULL, 2) → 1