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. Предикаты сравнения
Предикат Описание Пример(ы) |
---|
Между (включая границы интервала).
|
Не между (обратное к
|
Между, после сортировки граничных значений.
|
Не между, после сортировки граничных значений.
|
Не равно, при этом NULL воспринимается как обычное значение.
|
Равно, при этом NULL воспринимается как обычное значение.
|
Проверяет, является ли значение эквивалентным NULL.
|
Проверяет, отличается ли значение от NULL.
|
Проверяет, является ли значение эквивалентным NULL (нестандартный синтаксис). |
Проверяет, отличается ли значение от NULL (нестандартный синтаксис). |
Проверяет, является ли результат логического выражения значением true.
|
Проверяет, является ли результат логического выражения значением false или неизвестным.
|
Проверяет, является ли результат логического выражения значением false.
|
Проверяет, является ли результат логического выражения значением true или неизвестным.
|
Проверяет, является ли результат логического выражения неизвестным значением.
|
Проверяет, является ли результат логического выражения значением true или false.
|
Предикат BETWEEN
упрощает проверки интервала:
a
BETWEENx
ANDy
равнозначно
a
>=x
ANDa
<=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 FROMb
a
IS NOT DISTINCT FROMb
Для значений не 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
Заметьте, что проверка
не будет работать, так как выражение
= NULLNULL
считается не «равным» NULL
. (Значение NULL представляет неопределённость, и равны ли две неопределённости, тоже не определено.)
Подсказка
Некоторые приложения могут ожидать, что
вернёт true, если результатом выражение
= NULLвыражения
является 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, будут ложными одновременно. Например:
SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); SELECT ROW(table.*) IS NULL FROM table; -- выбор всех строк, содержащих только NULL SELECT ROW(table.*) IS NOT NULL FROM table; -- выбор всех строк, не содержащих NULL SELECT NOT(ROW(table.*) IS NOT NULL) FROM TABLE; -- выбор всех строк, содержащих хотя бы одно значение 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. Функции сравнения