PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

9.2. 比较函数与操作符 #

支持常用的关系比较操作符,如 Table 9.1.

Table 9.1. 比较操作符

操作符说明
datatype < datatype → boolean 小于
datatype > datatype → boolean 大于
datatype <= datatype → boolean 小于或等于
datatype >= datatype → boolean 大于或等于
datatype = datatype → boolean 等于
datatype <> datatype → boolean 不等于
datatype != datatype → boolean 不等于

Note

<> 是 SQL 标准规定的“不等于”记法。!= 是其同义别名,在语法解析的极早阶段便会被直接转换为 <>。因此,无法实现行为不同的 != 与 <> 操作符。

这些比较操作符适用于所有具备自然排序规则的内置数据类型,包括数值、字符串以及日期/时间类型。此外,若其组成元素的数据类型支持比较,数组、复合类型以及范围类型亦可进行比较。

通常亦可对相关联的数据类型的值进行相互比较;例如 integer > bigint 能够正常工作。某些此类场景直接由“跨类型”比较操作符实现;若不存在现成的跨类型操作符,语法解析器会将较具体的类型隐式强制转换为较通用的类型,并应用后者的比较操作符。

如上所示,所有比较操作符均为返回 boolean 类型值的二元操作符。因此,形如 1 < 2 < 3 的链式表达式是非法的(因为不存在将布尔值与整数 3 进行比较的 < 操作符)。请使用下文所示的 BETWEEN 谓词来执行范围检测。

此外还存在若干比较谓词,如 Table 9.2 所示。它们的行为与操作符非常相似,但具备 SQL 标准规定的特殊语法格式。

Table 9.2. 比较谓词

谓词语法

功能说明

示例

datatype BETWEEN datatype AND datatype → boolean

在区间范围内(包含两个端点值)。

2 BETWEEN 1 AND 3 → t

2 BETWEEN 3 AND 1 → f

datatype NOT BETWEEN datatype AND datatype → boolean

不在区间范围内(BETWEEN 的逻辑取反)。

2 NOT BETWEEN 1 AND 3 → f

datatype BETWEEN SYMMETRIC datatype AND datatype → boolean

在区间范围内,端点值无需按大小排序,系统会自动重排两个端点。

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

检测值是否为 SQL NULL 空值。

1.5 IS NULL → f

datatype IS NOT NULL → boolean

检测值是否不为 SQL NULL 空值。

'null' IS NOT NULL → t

datatype ISNULL → boolean

检测值是否为空值(非标准历史语法)。

datatype NOTNULL → boolean

检测值是否非空(非标准历史语法)。

boolean IS TRUE → boolean

检测布尔表达式是否计算为 TRUE。

true IS TRUE → t

NULL::boolean IS TRUE → f (而非 NULL)

boolean IS NOT TRUE → boolean

检测布尔表达式是否计算为 FALSE 或 UNKNOWN。

true IS NOT TRUE → f

NULL::boolean IS NOT TRUE → t (而非 NULL)

boolean IS FALSE → boolean

检测布尔表达式是否计算为 FALSE。

true IS FALSE → f

NULL::boolean IS FALSE → f (而非 NULL)

boolean IS NOT FALSE → boolean

检测布尔表达式是否计算为 TRUE 或 UNKNOWN。

true IS NOT FALSE → t

NULL::boolean IS NOT FALSE → t (而非 NULL)

boolean IS UNKNOWN → boolean

检测布尔表达式是否计算为 UNKNOWN。

true IS UNKNOWN → f

NULL::boolean IS UNKNOWN → t (而非 NULL)

boolean IS NOT UNKNOWN → boolean

检测布尔表达式是否计算为 TRUE 或 FALSE(即结果已知非 NULL)。

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 的各变体均基于底层常规比较操作符实现,因此适用于任何支持比较的数据类型。

Note

在 BETWEEN 语法中使用关键字 AND 会与作为逻辑操作符的 AND 产生语法歧义。为了消除歧义,仅允许受限的表达式类型作为 BETWEEN 子句的第二个参数。若需在 BETWEEN 中编写更复杂的子表达式,请在子表达式外层添加圆括号。

当任一输入操作数为 NULL 时,常规比较操作符将返回 NULL(表示“未知” UNKNOWN),而非 TRUE 或 FALSE。例如,7 = NULL 会返回 NULL,7 <> NULL 同样返回 NULL。若此默认三值逻辑行为不符合业务预期,请使用 IS [ NOT ] DISTINCT FROM 谓词:

a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b

对于非空输入,IS DISTINCT FROM 与 <> 操作符行为一致。但如果两个输入都为空值,它返回假;如果只有一个输入为空值,则返回真。类似地,对非空输入而言 IS NOT DISTINCT FROM 与 = 完全相同,但当两个输入都为空值时它返回真,只有一个输入为空值时返回假。因此,这些谓词实际上把空值当作普通数据值对待,而非当作 “未知”。

要检测一个值是否为空值,请使用以下谓词:

expression IS NULL
expression IS NOT NULL

或使用等效但非标准的谓词:

expression ISNULL
expression NOTNULL

请不要书写 expression = NULL,因为 NULL 与 NULL 并不“相等”。(空值表示一个未知的值,而两个未知的值是否相等无从得知。)

Tip

某些应用可能期望 expression = NULL 在 expression 求值为空值时返回真。强烈建议修改这些应用以符合 SQL 标准。但如果确实无法修改,可以使用 transform_null_equals 配置参数。启用该参数后, PostgreSQL 会把 x = NULL 子句转换为 x IS NULL。

如果 expression 是行值表达式,那么当行表达式本身为空或行的所有字段均为空时, IS NULL 为真;当行表达式本身非空且所有字段均非空时, IS NOT NULL 为真。由于这种行为,对行值表达式而言 IS NULL 与 IS NOT NULL 的结果并不总是互逆;特别是,同时包含空与非空字段的行值表达式对两个测试都会返回假。例如:

SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');

SELECT ROW(table.*) IS NULL FROM table;  -- detect all-null rows

SELECT ROW(table.*) IS NOT NULL FROM table;  -- detect all-non-null rows

SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- detect at least one null in rows

在某些情况下,更好的写法是使用 row IS DISTINCT FROM NULL 或 row IS NOT DISTINCT FROM NULL,它们只检查整行的值是否为空,而不对行字段做任何附加测试。

Boolean values can also be tested using the predicates

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

这些谓词总是返回真或假,即使操作数为空值也不会返回空值。 空输入被视为逻辑值 “未知”。注意 IS UNKNOWN 与 IS NOT UNKNOWN 实际上分别等同于 IS NULL 与 IS NOT NULL,只是要求输入表达式必须为布尔类型。

此外还有若干与比较相关的函数可用,如 Table 9.3 所示。

Table 9.3. 比较函数

函数

描述

示例

num_nonnulls ( VARIADIC "any" ) → integer

返回非空参数的数量。

num_nonnulls(1, NULL, 2) → 2

num_nulls ( VARIADIC "any" ) → integer

返回空参数的数量。

num_nulls(1, NULL, 2) → 1