Функции и операторы сравнения

Среди операторов сравнения имеются обычные операторы, перечисленные в Таблице 1.

Таблица 1. Операторы сравнения

ОператорОписание
тип_данных < тип_данныхbooleanМеньше
тип_данных > тип_данныхbooleanБольше
тип_данных <= тип_данныхbooleanМеньше или равно
тип_данных >= тип_данныхbooleanБольше или равно
тип_данных = тип_данныхbooleanРавно
тип_данных <> тип_данныхbooleanНе равно
тип_данных != тип_данныхbooleanНе равно

Примечание
Для условия «не равно» в стандарте SQL принята запись <>. Запись != является псевдонимом, который преобразуется в <> на самом раннем этапе синтаксического анализа. Как следствие, реализовать операторы != и <> так, чтобы они работали по-разному, невозможно.

Эти операторы сравнения имеются для всех встроенных типов данных с естественной сортировкой, включая числовые, строковые типы и типы даты/времени. Кроме того, сравниваться могут массивы, составные типы и диапазоны, если сравнимы типы данных их компонентов.

Обычно также можно сравнивать значения связанных типов данных; например, возможно сравнение integer > bigint. Некоторые подобные операции реализуются непосредственно «межтиповыми» операторами сравнения, но если такой оператор недоступен, синтаксический анализатор принудительно приведет менее распространенные тип к более распространенному и применит подходящий для последнего оператор сравнения.

Как показано выше, все операторы сравнения являются бинарными операторами, которые возвращают значения типа boolean. Таким образом, выражения типа 1 < 2 < 3 недопустимы (потому что нет оператора < для сравнения логического значения с 3). Для проверки принадлежности диапазону используйте предикат BETWEEN, описанный ниже

Существует также несколько предикатов сравнения, перечисленных в Таблице 2. Они ведут себя подобно операторам, но имеют специальный синтаксис, предписанный стандартом SQL.

Таблица 2. Предикаты сравнения

Предикат
Описание
Пример(ы)
тип_данных BETWEEN тип_данных AND тип_данных → boolean
Между (включая границы диапазона).
2 BETWEEN 1 AND 3 → t
2 BETWEEN 3 AND 1 → f
тип_данных NOT BETWEEN тип_данных AND тип_данных → boolean
Не между (обратное к BETWEEN).
2 NOT BETWEEN 1 AND 3 → f
тип_данных BETWEEN SYMMETRIC тип_данных AND тип_данных → boolean
Между, после сортировки граничных значений.
2 BETWEEN SYMMETRIC 3 AND 1 → t
тип_данных NOT BETWEEN SYMMETRIC тип_данных AND тип_данных → boolean
Не между, после сортировки граничных значений.
2 NOT BETWEEN SYMMETRIC 3 AND 1 → f
тип_данных IS DISTINCT FROM тип_данных → boolean
Не равно, при этом рассматривая NULL как обычное значение.
1 IS DISTINCT FROM NULL → t (а не NULL)
NULL IS DISTINCT FROM NULL → f (а не NULL)
тип_данных IS NOT DISTINCT FROM тип_данных → boolean
Равно, при этом рассматривая NULL как обычное значение.
1 IS NOT DISTINCT FROM NULL → f (а не NULL)
NULL IS NOT DISTINCT FROM NULL → t (а не NULL)
тип_данных IS NULL → boolean
Проверяет, равно ли значение NULL.
1.5 IS NULL → f
тип_данных IS NOT NULL → boolean
Проверяет, отличается ли значение от NULL.
'null' IS NOT NULL → t
тип_данных ISNULL → boolean
Проверяет, равно ли значение NULL (нестандартный синтаксис).
тип_данных NOTNULL → boolean
Проверяет, отличается ли значение от NULL (нестандартный синтаксис).
boolean IS TRUE → boolean
Проверяет, является ли результат логического выражения значением true.
true IS TRUE → t
NULL::boolean IS TRUE → f (а не NULL)
boolean IS NOT TRUE → boolean
Проверяет, является ли результат логического выражения значением false или неизвестным.
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 или неизвестным.
true IS NOT FALSE → t
NULL::boolean IS NOT FALSE → t (а не NULL)
boolean IS UNKNOWN → boolean
Проверяет, является ли результат логического выражения неизвестным значением.
true IS UNKNOWN → f
NULL::boolean IS UNKNOWN → t (а не NULL)
boolean IS NOT UNKNOWN → boolean
Проверяет, является ли результат логического выражения значением true или false.
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 реализуются посредством обычных операторов сравнения, и поэтому они будут работать с любыми типами данных, которые можно сравнивать.

Примечание
Использование AND в синтаксисе BETWEEN создает неоднозначность с использованием AND как логического оператора. Для ее устранения в качестве второго аргумента предложения BETWEEN допускается только ограниченный набор типов выражений. Если вам нужно записать в BETWEEN более сложное подвыражение, заключите его в скобки.

Обычные операторы сравнения выдают NULL (что означает «неопределенность»), а не true или false, когда любой из аргументов равен NULL. Например, 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, но возвращает true, если оба аргумента NULL, и false, если только один аргумент NULL. Таким образом, эти предикаты по сути ведут себя так, как если бы NULL был нормальным значением данных, а не «неопределенным».

Чтобы проверить, является ли значение NULL, используются предикаты:

выражение IS NULL
выражение IS NOT NULL

или равнозначные, но нестандартные предикаты:

выражение ISNULL
выражение NOTNULL

Не пишите выражение = NULL, потому что NULL «не равно» NULL. (Значение NULL представляет неопределенность, и неизвестно, равны ли два неопределенных значения).

Совет
Некоторые приложения могут ожидать, что выражение = NULL возвращает true, если результатом выражения является значение NULL. Настоятельно рекомендуется изменить эти приложения в соответствии со стандартом SQL. Однако если это невозможно, имеется переменная конфигурации transform_null_equals. Если она установлена, QHB преобразует предложения x = NULL в x IS NULL.

Если выражение имеет строковое значение, то IS NULL равно true, если само выражение строки NULL или когда все поля строки NULL, а IS NOT NULL равно true, если само выражение строки не NULL и все поля строки не NULL. Из-за этого поведения IS NULL и IS NOT NULL не всегда возвращают обратные результаты для таких выражений; в частности, строковое выражение, содержащее поля NULL и не NULL, вернет false для обеих проверок. В некоторых случаях может быть предпочтительнее записать строка IS DISTINCT FROM NULL или строка IS NOT DISTINCT FROM NULL, которые просто проверят, равно ли NULL все значение строки, без каких-либо дополнительных проверок полей строки.

Логические значения также можно проверить с использованием предикатов

логическое_выражение IS TRUE
логическое_выражение IS NOT TRUE
логическое_выражение IS FALSE
логическое_выражение IS NOT FALSE
логическое_выражение IS UNKNOWN
логическое_выражение IS NOT UNKNOWN

Они всегда будут возвращать true или false и никогда NULL, даже если операнд — NULL. Аргумент NULL рассматривается как логическое значение «неопределенность». Обратите внимание, что IS UNKNOWN и IS NOT UNKNOWN фактически то же самое, что и IS NULL и IS NOT NULL соответственно, за исключением того, что входное выражение должно иметь логический тип.

Также существует несколько связанных со сравнениями функций, перечисленных в Таблице 3.

Таблица 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