9.3 9.4 9.5 9.6 10 11 12 13 14 Current(15)
阿里云PostgreSQL 问题报告 纠错本页面

9.2. 比较函数和操作符

常见的比较操作符都可用,如表 9.1所示。

表 9.1. 比较操作符

操作符描述
datatype < datatypeboolean 小于
datatype > datatypeboolean 大于
datatype <= datatypeboolean 小于等于
datatype >= datatypeboolean 大于等于
datatype = datatypeboolean 等于
datatype <> datatypeboolean 不等于
datatype != datatypeboolean 不等于

注意

<> 表示 not equal 的标准的SQL符号。 != 是一个别名, 在解析的早期阶段被转换为 <> 。 因此, 它不可能实现 !=<> 操作符以做不同的事情。

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

通常也可以比较相关数据类型的值;例如integer > bigint 将起作用。 这种排序的某些情况直接由cross-type 比较操作符实现,但是,如果没有这种操作符,解析器将把不太通用的类型强制为更通用的类型,并应用后者的比较操作符。

如上所示,所有比较操作符都是二元操作符,返回boolean类型的值。 因此,类似1 < 2 < 3的表达式是无效的。因为没有<操作符与 3 进行Boolean值比较)。 使用下面显示的BETWEEN谓词执行范围测试。

表 9.2所示,也有一些比较谓词。它们的行为和操作符很像,但是具有 SQL 标准所要求的特殊语法。

表 9.2. 比较谓词

谓词

描述

示例(s)

datatype BETWEEN datatype AND datatypeboolean

之间(包括范围端点)。

2 BETWEEN 1 AND 3t

2 BETWEEN 3 AND 1f

datatype NOT BETWEEN datatype AND datatypeboolean

不在之间 (BETWEEN的否定).

2 NOT BETWEEN 1 AND 3f

datatype BETWEEN SYMMETRIC datatype AND datatypeboolean

之间, 在对两个端点值排序之后。

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

测试值是否为空。

1.5 IS NULLf

datatype IS NOT NULLboolean

测试值是否不为空。

'null' IS NOT NULLt

datatype ISNULLboolean

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

datatype NOTNULLboolean

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

boolean IS TRUEboolean

测试布尔表达式是否为真。

true IS TRUEt

NULL::boolean IS TRUEf (而不是 NULL)

boolean IS NOT TRUEboolean

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

true IS NOT TRUEf

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

boolean IS FALSEboolean

测试布尔表达式是否为假。

true IS FALSEf

NULL::boolean IS FALSEf (而不是 NULL)

boolean IS NOT FALSEboolean

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

true IS NOT FALSEt

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

boolean IS UNKNOWNboolean

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

true IS UNKNOWNf

NULL::boolean IS UNKNOWNt (而不是 NULL)

boolean IS NOT UNKNOWNboolean

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

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中写一个更复杂的子表达式,在子表达式两边写上圆括号。

当有一个输入为空时,普通的比较操作符会得到空(表示未知),而不是真或假。例如,7 = NULL得到空,7 <> NULL也一样。如果这种行为不合适,可以使用IS [ NOT ] DISTINCT FROM谓词:

a IS DISTINCT FROM b
a IS NOT DISTINCT FROM b

对于非空输入,IS DISTINCT FROM<>操作符一样。不过,如果两个输入都为空,它会返回假。而如果只有一个输入为空,它会返回真。类似地,IS NOT DISTINCT FROM对于非空输入的行为与=相同,但是当两个输入都为空时它返回真,并且当只有一个输入为空时返回假。因此,这些谓词实际上把空值当作一种普通数据值而不是unknown

要检查一个值是否为空,使用下面的谓词:

expression IS NULL
expression IS NOT NULL

或者等效,但并不标准的谓词:

expression ISNULL
expression NOTNULL

不要expression = NULL,因为NULL是不等于NULL的(控制代表一个未知的值,因此我们无法知道两个未知的数值是否相等)。

提示

有些应用可能要求表达式expression = NULLexpression得出空值时返回真。我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改不可能完成,那么我们可以使用配置变量transform_null_equals。如果打开它,PostgreSQL将把x = NULL子句转换成x IS NULL

如果expression是行值,那么当行表达式本身为非空值或者行的所有域为非空时IS NULL为真。由于这种行为,IS NULLIS NOT NULL并不总是为行值表达式返回反转的结果,特别是,一个同时包含 NULL 和非空值的域将会对两种测试都返回假。在某些情况下,写成row IS DISTINCT FROM NULL或者row IS NOT DISTINCT FROM 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

这些谓词将总是返回真或假,从来不返回空值,即使操作数是空也如此。空值输入被当做逻辑值未知。 请注意实际上IS UNKNOWNIS NOT UNKNOWN分别与IS NULLIS NOT NULL相同, 只是输入表达式必须是布尔类型。

表 9.3中所示,也有一些比较相关的函数可用。

表 9.3. 比较函数

函数

描述

例子

num_nonnulls ( VARIADIC "any" ) → integer

返回非空参数的数量。

num_nonnulls(1, NULL, 2)2

num_nulls ( VARIADIC "any" ) → integer

返回空参数的数量。

num_nulls(1, NULL, 2)1