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 #
expressionIN (subquery)
Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно один столбец. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса. Результат оператора IN будет “true”, если найдена хотя бы одна равная строка подзапроса. Результат будет “false”, если равная строка не найдена (включая случай, когда подзапрос не возвращает ни одной строки).
Обратите внимание, что если левое выражение возвращает null, или если нет равных значений справа и хотя бы одна строка справа возвращает null, результат конструкции IN будет null, а не false. Это соответствует обычным правилам SQL для логических комбинаций null значений.
Как и с EXISTS, неразумно предполагать, что подзапрос будет
полностью вычислен.
row_constructorIN (subquery)
Левая часть этой формы IN является конструктором строки, как описано в Раздел 4.2.13.
Правая часть - это вложенный подзапрос, который должен вернуть ровно столько же столбцов, сколько выражений в левой строке. Левые выражения вычисляются и сравниваются построчно с каждой строкой результата подзапроса.
Результат IN будет “true”, если найдена хотя бы одна равная строка подзапроса.
Результат будет “false”, если равная строка не найдена (включая случай, когда подзапрос не возвращает строк).
Как обычно, значения null в строках объединяются в соответствии с обычными правилами логических выражений SQL. Две строки считаются равными, если все их соответствующие элементы не являются null и равны; строки считаются неравными, если хотя бы один из соответствующих элементов не является null и не равен; в противном случае результат сравнения строк будет неизвестен (null).
Если все результаты сравнения строк либо неравны, либо null, и хотя бы один из них является null, то результат оператора IN будет null.
9.23.3. NOT IN #
expressionNOT IN (subquery)
Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно одну колонку. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса. Результат оператора NOT IN будет “true”, если найдены только неравные строки подзапроса (включая случай, когда подзапрос не возвращает строк). Результат будет “false”, если найдена хотя бы одна равная строка.
Обратите внимание, что если левое выражение дает значение null, или если нет равных значений справа и хотя бы одна строка справа дает значение null, результат конструкции NOT IN будет null, а не true. Это соответствует обычным правилам SQL для логических комбинаций значений null.
Как и с EXISTS, неразумно предполагать, что подзапрос будет
полностью вычислен.
row_constructorNOT 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 #
expressionoperatorANY (subquery)expressionoperatorSOME (subquery)
Правая сторона представляет собой подзапрос, заключенный в скобки, который должен вернуть ровно один столбец. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса с использованием заданного operator, который должен давать логический результат.
Результат ANY будет “true”, если получен хотя бы один истинный результат.
Результат будет “false”, если истинный результат не найден (включая случай, когда подзапрос не возвращает строк).
SOME является синонимом для ANY.
IN эквивалентно = ANY.
Обратите внимание, что если нет успешных сравнений и хотя бы одна строка справа возвращает null в результате оператора, результат конструкции ANY будет null, а не false.
Это соответствует обычным правилам SQL для логических комбинаций значений null.
Как и с EXISTS, неразумно предполагать, что подзапрос будет
полностью вычислен.
row_constructoroperatorANY (subquery)row_constructoroperatorSOME (subquery)
Левая часть этой формы ANY представляет собой конструктор строки,
как описано в Раздел 4.2.13.
Правая часть представляет собой заключенный в скобки
подзапрос, который должен вернуть ровно столько же столбцов, сколько есть
выражений в левой строке. Левые выражения
оцениваются и сравниваются построчно с каждой строкой результата подзапроса,
используя заданный operator.
Результат ANY будет “true”, если сравнение
возвращает true для любой строки подзапроса.
Результат будет “false”, если сравнение возвращает false для каждой
строки подзапроса (включая случай, когда подзапрос не возвращает
строки).
Результат будет NULL, если ни одно сравнение со строкой подзапроса не вернет true,
и хотя бы одно сравнение вернет NULL.
См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.
9.23.5. ALL #
expressionoperatorALL (subquery)
Правая часть является подзапросом в скобках, который должен вернуть ровно одну колонку. Левое выражение вычисляется и сравнивается с каждой строкой результата подзапроса с использованием заданного operator, который должен давать логический результат.
Результат ALL будет “true”, если все строки дают true (включая случай, когда подзапрос не возвращает строк).
Результат будет “false”, если найден хотя бы один ложный результат.
Результат будет NULL, если ни одно сравнение с строкой подзапроса не дает ложный результат, и хотя бы одно сравнение дает NULL.
NOT IN эквивалентно <> ALL.
Как и с EXISTS, неразумно предполагать, что подзапрос будет
полностью вычислен.
row_constructoroperatorALL (subquery)
Левая часть этой формы ALL является конструктором строки,
как описано в Раздел 4.2.13.
Правая часть - это заключенный в скобки подзапрос, который должен вернуть ровно столько же столбцов, сколько выражений в левой строке.
Левые выражения вычисляются и сравниваются построчно с каждой строкой результата подзапроса, используя заданный operator.
Результат ALL будет “true”, если сравнение вернет true для всех строк подзапроса (включая случай, когда подзапрос не возвращает строк).
Результат будет “false”, если сравнение вернет false для любой строки подзапроса.
Результат будет NULL, если ни одно сравнение с строкой подзапроса не вернет false, и хотя бы одно сравнение вернет NULL.
См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.
9.23.6. Одиночное сравнение строк #
row_constructoroperator(subquery)
Левая сторона - это конструктор строки, как описано в Раздел 4.2.13. Правая сторона - это вложенный подзапрос, который должен вернуть ровно столько же столбцов, сколько выражений в строке левой стороны. Кроме того, подзапрос не может вернуть более одной строки. (Если он возвращает ноль строк, результат считается нулевым). Левая сторона вычисляется и сравнивается построчно с результатом подзапроса.
См. Раздел 9.24.5 для получения подробной информации о значении сравнения конструктора строк.