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

Набор операторов сравнения включает обычные операторы, перечисленные в Таблице 9.1.

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

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

Примечание

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

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

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

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

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

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

Предикат

Описание

Пример(ы)

тип_данныхBETWEENтип_данныхANDтип_данныхboolean

Между (включая границы интервала).

2 BETWEEN 1 AND 3t

2 BETWEEN 3 AND 1f

тип_данныхNOT BETWEENтип_данныхANDтип_данныхboolean

Не между (обратное к BETWEEN).

2 NOT BETWEEN 1 AND 3f

тип_данныхBETWEEN SYMMETRICтип_данныхANDтип_данныхboolean

Между, после сортировки граничных значений.

2 BETWEEN SYMMETRIC 3 AND 1t

тип_данныхNOT BETWEEN SYMMETRICтип_данныхANDтип_данныхboolean

Не между, после сортировки граничных значений.

2 NOT BETWEEN SYMMETRIC 3 AND 1f

тип_данныхIS DISTINCT FROMтип_данныхboolean

Не равно, при этом NULL воспринимается как обычное значение.

1 IS DISTINCT FROM NULLt (а не NULL)

NULL IS DISTINCT FROM NULLf (а не NULL)

тип_данныхIS NOT DISTINCT FROMтип_данныхboolean

Равно, при этом NULL воспринимается как обычное значение.

1 IS NOT DISTINCT FROM NULLf (а не NULL)

NULL IS NOT DISTINCT FROM NULLt (а не NULL)

тип_данныхIS NULLboolean

Проверяет, является ли значение эквивалентным NULL.

1.5 IS NULLf

тип_данныхIS NOT NULLboolean

Проверяет, отличается ли значение от NULL.

'null' IS NOT NULLt

тип_данныхISNULLboolean

Проверяет, является ли значение эквивалентным NULL (нестандартный синтаксис).

тип_данныхNOTNULLboolean

Проверяет, отличается ли значение от NULL (нестандартный синтаксис).

booleanIS TRUEboolean

Проверяет, является ли результат логического выражения значением true.

true IS TRUEt

NULL::boolean IS TRUEf (а не NULL)

booleanIS NOT TRUEboolean

Проверяет, является ли результат логического выражения значением false или неизвестным.

true IS NOT TRUEf

NULL::boolean IS NOT TRUEt (а не NULL)

booleanIS FALSEboolean

Проверяет, является ли результат логического выражения значением false.

true IS FALSEf

NULL::boolean IS FALSEf (а не NULL)

booleanIS NOT FALSEboolean

Проверяет, является ли результат логического выражения значением true или неизвестным.

true IS NOT FALSEt

NULL::boolean IS NOT FALSEt (а не NULL)

booleanIS UNKNOWNboolean

Проверяет, является ли результат логического выражения неизвестным значением.

true IS UNKNOWNf

NULL::boolean IS UNKNOWNt (а не NULL)

booleanIS NOT UNKNOWNboolean

Проверяет, является ли результат логического выражения значением true или false.

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 реализуются посредством обычных операторов сравнения, и поэтому они будут работать с любыми типами данных, которые можно сравнивать.

Примечание

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

Обычные операторы сравнения выдают NULL (что означает «неопределённость»), а не true или false, когда любое из сравниваемых значений NULL. Например, 7 = NULL выдаёт NULL, так же, как и 7 <> NULL. Когда это поведение нежелательно, можно использовать предикаты IS [ NOT ] DISTINCT FROM:

a IS DISTINCT FROM ba IS NOT DISTINCT FROM b

Для значений не NULL условие IS DISTINCT FROM работает так же, как оператор <>. Однако если оба сравниваемых значения NULL, результат будет false, и только если одно из значений NULL, возвращается true. Аналогично, условие IS NOT DISTINCT FROM равносильно = для значений не NULL, но возвращает true, если оба сравниваемых значения NULL, и false в противном случае. Таким образом, эти предикаты по сути работают с NULL, как с обычным значением, а не с «неопределённостью».

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

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

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

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

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

Подсказка

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

Если выражение возвращает табличную строку, тогда IS NULL будет истинным, когда само выражение — NULL или все поля строки — NULL, а IS NOT NULL будет истинным, когда само выражение не NULL, и все поля строки так же не NULL. Вследствие такого определения, IS NULL и IS NOT NULL не всегда будут возвращать взаимодополняющие результаты для таких выражений; в частности такие выражения со строками, одни поля которых NULL, а другие не NULL, будут ложными одновременно. В некоторых случаях имеет смысл написать строка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, соответственно, за исключением того, что выражение может быть только булевого типа.

Также имеется несколько связанных со сравнениями функций; они перечислены в Таблице 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


close