9.24. Сравнения строк и массивов#
9.24. Сравнения строк и массивов
Этот раздел описывает несколько специализированных конструкций для сравнения между группами значений. Эти формы синтаксически связаны с формами подзапросов предыдущего раздела, но не включают подзапросы. Формы, включающие массивные подвыражения, являются расширениями Tantor BE; остальные совместимы с SQL. Все формы выражений, документированные в этом разделе, возвращают логические (true/false) результаты.
9.24.1. IN
expression
IN (value
[, ...])
Правая сторона - это список выражений в скобках. Результат будет “истинным”, если результат выражения слева равен любому из выражений справа. Это сокращенная запись для
expression
=value1
ORexpression
=value2
OR ...
Обратите внимание, что если левое выражение возвращает null, или если нет равных значений справа и хотя бы одно правое выражение возвращает null, результат конструкции IN
будет null, а не false. Это соответствует обычным правилам SQL для логических комбинаций null значений.
9.24.2. NOT IN
expression
NOT IN (value
[, ...])
Правая сторона - это список выражений в скобках. Результат будет “истинным”, если результат выражения слева не равен всем выражениям справа. Это сокращенная запись для
expression
<>value1
ANDexpression
<>value2
AND ...
Обратите внимание, что если левое выражение возвращает null или если нет равных значений справа и хотя бы одно выражение справа возвращает null, результат конструкции NOT IN
будет null, а не true, как можно было бы ожидать.
Это соответствует обычным правилам SQL для логических комбинаций null значений.
Подсказка
x NOT IN y
эквивалентно NOT (x IN y)
во всех случаях. Однако, значения null гораздо чаще могут запутать новичка при работе с NOT IN
, чем при работе с IN
. Лучше выражать условие положительно, если это возможно.
9.24.3. ANY
/SOME
(array)
expression
operator
ANY (array expression
)expression
operator
SOME (array expression
)
Правая сторона - это выражение в скобках, которое должно давать значение массива.
Левое выражение
вычисляется и сравнивается с каждым элементом массива с использованием
заданного operator
, который должен давать логический
результат.
Результат ANY
равен “true”, если получен хотя бы один истинный результат.
Результат равен “false”, если истинный результат не найден (включая
случай, когда массив не содержит элементов).
Если выражение массива дает пустой массив, результатом оператора ANY
будет null. Если левое выражение дает null, результатом оператора ANY
обычно будет null (хотя нестрогий оператор сравнения может дать другой результат). Также, если правый массив содержит null элементы и не получается истинный результат сравнения, результатом оператора ANY
будет null, а не false (снова, при условии строгого оператора сравнения). Это соответствует обычным правилам SQL для логических комбинаций null значений.
SOME
является синонимом для ANY
.
9.24.4. ALL
(array)
expression
operator
ALL (array expression
)
Правая сторона - это выражение в скобках, которое должно давать значение массива.
Левое выражение
вычисляется и сравнивается с каждым элементом массива с использованием
заданного operator
, который должен давать логический
результат.
Результат ALL
будет “true”, если все сравнения дадут true
(включая случай, когда массив не содержит элементов).
Результат будет “false”, если найден хотя бы один false результат.
Если выражение массива дает пустой массив, результатом операции ALL
будет null. Если левое выражение дает null, результат операции ALL
обычно будет null (хотя нестрогий оператор сравнения может дать другой результат). Также, если правый массив содержит null элементы и не получается ложный результат сравнения, результатом операции ALL
будет null, а не true (снова, при условии строгого оператора сравнения). Это соответствует обычным правилам SQL для логических комбинаций null значений.
9.24.5. Сравнение конструктора строк
row_constructor
operator
row_constructor
Каждая сторона является конструктором строки,
как описано в Раздел 4.2.13.
Оба конструктора строк должны иметь одинаковое количество полей.
Указанный operator
применяется к каждой паре
соответствующих полей. (Поскольку поля могут быть разных
типов, это означает, что для каждой пары может быть выбран
разный конкретный оператор.)
Все выбранные операторы должны быть членами какого-либо класса операторов B-дерева,
или быть отрицанием члена =
класса операторов B-дерева, что означает, что сравнение конструкторов строк возможно только
когда operator
является
=
,
<>
,
<
,
<=
,
>
, или
>=
,
или имеет семантику, аналогичную одной из этих.
Случаи с использованием =
и <>
работают немного иначе, чем остальные. Две строки считаются равными, если все их соответствующие элементы не являются нулевыми и равны между собой; строки считаются неравными, если хотя бы один из соответствующих элементов не является нулевым и не равен другому; в противном случае результат сравнения строк неизвестен (null).
Для случаев <
, <=
, >
и
>=
элементы строки сравниваются слева направо,
останавливаясь, как только найдена неравная или нулевая пара элементов.
Если хотя бы один из этой пары элементов является нулевым, результат
сравнения строк неизвестен (null); в противном случае результат определяется
сравнением этой пары элементов. Например,
ROW(1,2,NULL) < ROW(1,3,0)
дает значение true, а не null, потому что третья пара элементов не
учитывается.
Примечание
До версии PostgreSQL 8.2, случаи <
, <=
, >
и >=
не обрабатывались в соответствии с SQL-спецификацией. Сравнение вида ROW(a,b) < ROW(c,d)
реализовывалось как a < c AND b < d
, в то время как правильное поведение эквивалентно a < c OR (a = c AND b < d)
.
row_constructor
IS DISTINCT FROMrow_constructor
Эта конструкция похожа на сравнение строк <>
, но она не возвращает null для null-входных данных. Вместо этого любое null-значение считается неравным (отличным) от любого ненулевого значения, и любые два null-значения считаются равными (неотличимыми). Таким образом, результат будет либо true, либо false, но никогда null.
row_constructor
IS NOT DISTINCT FROMrow_constructor
Эта конструкция аналогична сравнению строк =
, но она не возвращает значение null для пустых входных данных. Вместо этого любое пустое значение считается неравным (отличным) от любого значения not-null, и любые два пустых значения считаются равными (неотличимыми). Таким образом, результат всегда будет либо true, либо false, никогда null.
9.24.6. Сравнение составного типа
record
operator
record
Спецификация SQL требует, чтобы сравнение построчно возвращало NULL, если результат зависит от сравнения двух NULL значений или NULL и ненулевого значения. Tantor BE делает это только при сравнении результатов двух конструкторов строк (как в Раздел 9.24.5) или сравнении конструктора строки с результатом подзапроса (как в Раздел 9.23). В других контекстах, где сравниваются два значения составного типа, два NULL значения поля считаются равными, а NULL считается больше ненулевого значения. Это необходимо для обеспечения последовательного поведения сортировки и индексации для составных типов.
Каждая сторона вычисляется и они сравниваются построчно. Сравнения составных типов разрешены, когда operator
равен =
, <>
, <
, <=
, >
или >=
, или имеет семантику, аналогичную одному из них. (А именно, оператор может быть оператором сравнения строк, если он является членом класса операторов B-дерева или является отрицанием члена =
класса операторов B-дерева). Поведение по умолчанию для вышеуказанных операторов такое же, как для IS [ NOT ] DISTINCT FROM
для конструкторов строк (см. Раздел 9.24.5).
Для поддержки сопоставления строк, которые включают элементы без операторного класса B-дерева по умолчанию, определены следующие операторы для сравнения составного типа:
*=
,
*<>
,
*<
,
*<=
,
*>
и
*>=
.
Эти операторы сравнивают внутреннее двоичное представление двух строк. Две строки могут иметь разное двоичное представление, даже если сравнение двух строк с оператором равенства истинно.
Порядок строк при использовании этих операторов сравнения является детерминированным, но в остальном не имеет смысла. Эти операторы используются внутренне для материализованных представлений и могут быть полезны для других специализированных целей, таких как репликация и дедупликация B-дерева (см. Раздел 64.4.3). Однако они не предназначены для общего использования при написании запросов.