9.23. Подзапросы#

9.23. Подзапросы

9.23. Подзапросы

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

9.23.1. EXISTS

EXISTS (subquery)

Аргументом 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);

9.23.2. IN

expression IN (subquery)

Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно одну колонку. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса. Результат оператора IN будет true, если найдена хотя бы одна равная строка подзапроса. Результат будет false, если равная строка не найдена (включая случай, когда подзапрос не возвращает ни одной строки).

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

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

row_constructor IN (subquery)

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

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

9.23.3. NOT IN

expression NOT IN (subquery)

Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно одну колонку. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса. Результат оператора NOT IN будет true, если найдены только неравные строки подзапроса (включая случай, когда подзапрос не возвращает строк). Результат будет false, если найдена хотя бы одна равная строка.

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

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

row_constructor NOT IN (subquery)

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

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

9.23.4. ANY/SOME

expression operator ANY (subquery)
expression operator SOME (subquery)

Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно одну колонку. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса с использованием заданного operator, который должен давать логический результат. Результат ANY будет true, если получен хотя бы один истинный результат. Результат будет false, если истинный результат не найден (включая случай, когда подзапрос не возвращает строк).

SOME является синонимом для ANY. IN эквивалентно = ANY.

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

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

row_constructor operator ANY (subquery)
row_constructor operator SOME (subquery)

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

См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.

9.23.5. ALL

expression operator ALL (subquery)

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

NOT IN эквивалентно <> ALL.

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

row_constructor operator ALL (subquery)

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

См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.

9.23.6. Одиночное сравнение строк

row_constructor operator (subquery)

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

См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.