Сравнение строк и массивов

В этом разделе описывается несколько специализированных конструкций для множественных сравнений между группами значений. Эти формы синтаксически связаны с формами подзапросов предыдущего раздела, но не включают подзапросы. Формы, включающие подвыражения массива, являются расширениями QHB; остальные SQL-совместимы. Все формы выражений, описанные в этом разделе, возвращают логические (true/false) результаты.


IN

выражение IN (значение [, ...])

Правая часть представляет собой заключенный в скобки список скалярных выражений. Если результат выражения слева равен любому из выражений справа, результатом будет «true». Это сокращенная запись для условия

выражение = значение1
OR
выражение = значение2
OR
...

Обратите внимание, что если выражение слева выдает NULL или если нет равных ему значений справа и хотя бы одно выражение справа выдает NULL, результатом конструкции IN будет NULL, а не false. Это соответствует обычным правилам SQL для логических комбинаций значений NULL.


NOT IN

выражение NOT IN (значение [, ...])

Правая часть представляет собой заключенный в скобки список скалярных выражений. Если результат выражения слева не равен всем выражениям справа, результатом будет «true». Это сокращенная запись для условия

выражение <> значение1
AND
выражение <> значение2
AND
...

Обратите внимание, что если выражение слева выдает NULL или если нет равных ему значений справа и хотя бы одно выражение справа выдает NULL, результатом конструкции NOT IN будет NULL, а не true , как можно было ожидать. Это соответствует обычным правилам SQL для логических комбинаций значений NULL.

Совет
x NOT IN y во всех случаях равнозначно NOT (x IN y). Тем не менее значения NULL гораздо чаще ставят в тупик новичков при работе с NOT IN, чем при работе с IN. Лучше всего по возможности выражать условие без отрицаний.


ANY/SOME (с массивом)

выражение оператор ANY (выражение массива)
выражение оператор SOME (выражение массива)

Правая часть представляет собой заключенное в скобки выражение, которое должно выдавать значение массива. Выражение слева вычисляется и сравнивается с каждым элементом массива с помощью указанного оператора, который должен выдавать логический результат. Если какой-либо полученный результат является true, результатом ANY будет «true». Если же результат true не находится (включая случай, когда массив имеет ноль элементов), то результатом будет «false».

Если выражение массива выдает массив NULL, результатом ANY будет NULL. Если выражение слева выдает NULL, то результат ANY обычно равен NULL (хотя оператор нестрогого сравнения может выдать и другой результат). Кроме того, если массив справа содержит какие-либо элементы NULL и не получено ни одного результата сравнения, равного true, результат ANY будет NULL, а не false (опять-таки, предполагая, что используется оператор строгого сравнения). Это соответствует обычным правилам SQL для логических комбинаций значений NULL.

Конструкция SOME является синонимом для ANY.


ALL (с массивом)

выражение оператор ALL (выражение массива)

Правая часть представляет собой заключенное в скобки выражение, которое должно выдавать значение массива. Выражение слева вычисляется и сравнивается с каждым элементом массива с помощью указанного оператора, который должен выдавать логический результат. Если все сравнения выдают true (включая случай, когда массив имеет ноль элементов), результатом ALL будет «true». Если же находится какой-либо результат false, то результатом будет «false».

Если выражение массива выдает массив NULL, результат ALL будет NULL. Если выражение слева выдает NULL, то результат ALL обычно равен NULL (хотя оператор нестрогого сравнения может выдать и другой результат). Кроме того, если массив справа содержит какие-либо элементы NULL и не получено ни одного результата сравнения, равного false, результат ALL будет NULL, а не true (опять-таки, предполагая, что используется оператор строгого сравнения). Это соответствует обычным правилам SQL для логических комбинаций значений NULL.


Сравнение конструкторов строк

конструктор_строки оператор конструктор_строки

Каждая сторона является конструктором строки, описанным в подразделе Конструкторы строк. Два значения строки должны иметь одинаковое количество полей. Каждая сторона вычисляется, а затем они построчно сравниваются. Сравнения конструкторов строк допускаются, когда оператором является =, <>, <, <=, > или >=. Каждый элемент строки должен иметь тип, для которого определен класс операторов B-дерева по умолчанию, иначе попытка сравнения может вызвать ошибку.

Примечание
Ошибки, связанные с количеством или типами элементов, могут не возникнуть, если сравнение разрешается со столбцами, полученными ранее.

В случае = и <> все работает немного по-другому. Две строки считаются равными, если все их соответствующие члены отличны от NULL и равны; строки являются неравными, если любые соответствующие члены отличны от NULL и не равны; в противном случае результат сравнения строк неизвестен (NULL).

Для случаев <, <=, > и >= элементы строки сравниваются слева направо, останавливаясь, как только обнаруживается неравная или равная NULL пара элементов. Если любой из этой пары элементов равен NULL, результат сравнения строк будет неизвестен (NULL); в ином случае сравнение этой пары элементов определяет результат. Например, ROW(1,2,NULL) < ROW(1,3,0) выдает значение true, а не NULL, поскольку третья пара элементов не рассматривается.

конструктор_строки IS DISTINCT FROM конструктор_строки

Эта конструкция похожа на сравнение строк <>, но она не выдает NULL для входных данных, равных NULL. Вместо этого любое значение NULL считается неравным (отличным от) любого значения не NULL, а любые два значения NULL считаются равными (не отличными). Таким образом, результат будет либо true, либо false, но не NULL.

конструктор_строки IS NOT DISTINCT FROM конструктор_строки

Эта конструкция похожа на сравнение строк =, но она не выдает NULL для входных данных, равных NULL. Вместо этого любое значение NULL считается неравным (отличным от) любого значения не NULL, а любые два значения NULL считаются равными (не отличными). Таким образом, результат будет либо true, либо false, но не NULL.


Сравнение составных типов

запись оператор запись

Спецификация SQL требует, чтобы построчное сравнение возвращало NULL, если результат зависит от сравнения двух значений NULL или значения NULL со значением не NULL. QHB делает это только при сравнении результатов двух конструкторов строк (как в подразделе Сравнение конструкторов строк) или при сравнении конструктора строки с выходными данными подзапроса (как в разделе Выражения подзапросов). В других контекстах, где сравниваются два значения составного типа, два значения поля NULL считаются равными, а NULL считается больше, чем не NULL. Это необходимо для согласованного поведения сортировки и индексации составных типов.

Каждая сторона вычисляется, а затем они сравниваются построчно. Сравнения составных типов допускаются, когда оператором является =, <>, <, <=, > или >=, либо его семантика аналогична одному из них. (Точнее говоря, оператор может быть оператором сравнения строк, если является членом класса операторов B-дерева или инвертен оператору = из класса операторов B-дерева). Поведение по умолчанию вышеупомянутых операторов такое же, как у выражениям IS [NOT] DISTINCT FROM для конструкторов строк (см. подраздел Сравнение конструкторов строк).

Для поддержки сопоставления строк, включающих в себя элементы, для которых не определен класс операторов B-дерева по умолчанию, определены следующие операторы сравнения составных типов: *=, *<>, *<, *<=, *> и *>=. Эти операторы сравнивают внутреннее двоичное представление двух строк. Две строки могут иметь различное двоичное представление, даже если при сравнении двух строк с оператором равенства результат равен true. Порядок строк в этих операторах сравнения детерминирован, но в остальном не имеет значения. Эти операторы применяются внутри системы для материализованных представлений и могут быть полезны для других специализированных целей, таких как репликация и дедупликация в B-дереве (см. подраздел Дедупликация), но не предназначены для общего использования при написании запросов.