Выражения подзапросов

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


EXISTS

EXISTS (подзапрос)

Аргументом EXISTS является произвольный оператор SELECT или подзапрос. Подзапрос вычисляется, чтобы определить, возвращает ли он какие-либо строки. Если он возвращает хотя бы одну строку, результат EXISTS равен «true»; если подзапрос не возвращает строк, результатом EXISTS будет «false».

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

Подзапрос, как правило, выполняется только до того момента, когда можно определить, возвращена ли хотя бы одна строка, а не до полного завершения. Неразумно писать подзапрос с побочными эффектами (например, вызовом функций последовательностей); возникновение побочных эффектов может быть непредсказуемым.

Поскольку результат зависит только от того, возвращаются ли какие-либо строки, а не от содержимого этих строк, выходной список подзапроса, как правило не важен. Обычное соглашение о кодировании — записывать все проверки EXISTS в форме EXISTS(SELECT 1 WHERE ...). Однако из этого правила есть исключения, такие как подзапросы с предложением INTERSECT.

Этот простой пример похож на внутреннее соединение по col2, но он генерирует не более одной выходной строки для каждой строки tab1, даже если есть несколько совпадающих строк tab2:

SELECT col1
FROM tab1
WHERE EXISTS (SELECT 1 FROM tab2 WHERE col2 = tab1.col2);

IN

выражение IN (подзапрос)

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

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

Как и в случае с EXISTS, не стоит предполагать, что подзапрос будет вычислен полностью.

конструктор_строки IN (подзапрос)

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

Как обычно, значения NULL в строках объединяются в соответствии с типичными правилами логических выражений SQL. Две строки считаются равными, если все их соответствующие члены отличны от NULL и равны между собой; строки являются неравными, если любые соответствующие члены отличны от NULL и не равны между собой; в противном случае результат сравнения строк неизвестен (NULL). Если все построчные результаты не равны между собой или равны NULL (достаточно и одного значения NULL), то результатом IN будет NULL.


NOT IN

выражение NOT IN (подзапрос)

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

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

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

конструктор_строки NOT IN (подзапрос)

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

Как обычно, значения NULL в строках объединяются в соответствии с типичными правилами логических выражений SQL. Две строки считаются равными, если все их соответствующие члены отличны от NULL и равны между собой; строки являются неравными, если любые соответствующие члены отличны от NULL и не равны между собой; в противном случае результат сравнения строк неизвестен (NULL). Если все построчные результаты не равны между собой или равны NULL (достаточно и одного значения NULL) то результатом NOT IN будет NULL.


ANY/SOME

выражение оператор ANY (подзапрос)

выражение оператор SOME (подзапрос)

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

Конструкция SOME является синонимом для ANY. Конструкция IN равнозначна = ANY.

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

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

конктруктор_строки оператор ANY (подзапрос)
конктруктор_строки оператор SOME (подзапрос)

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

Подробную информацию о семантике сравнения конструкторов строк см. в подразделе Сравнение конструкторов строк.


ALL

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

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

Конструкция NOT IN равнозначна <> ALL.

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

конструктор_строки оператор ALL (подзапрос)

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

Подробную информацию о семантике сравнения конструкторов строк см. в подразделе Сравнение конструкторов строк.


Сравнение единичных строк

конструктор_строки оператор (подзапрос)

Левая часть является конструктором строки, описанным в подразделе Конструкторы строк. Правая часть — это заключенный в скобки подзапрос, который должен возвращать ровно столько столбцов, сколько имеется выражений в строке слева. Более того, подзапрос не может возвращать более одной строки. (Если он возвращает ноль строк, результат принимается равным NULL). Левая часть вычисляется и построчно сравнивается с единственной строкой результата подзапроса.

Подробную информацию о семантике сравнения конструкторов строк см. в подразделе Сравнение конструкторов строк.