Вставка одного подзапроса внутрь другого

 

Вложенный подзапрос - это подзапрос, заключенный в круглые скобки и вложенный в предложение WHERE (HAVING) команды SELECT. Вложенный подзапрос может содержать в своём WHERE (HAVING) предложении другой вложенный подзапрос и т.д.

Пример:

1) Вывести информацию о последних проводках по счету 20202840600000000000.

 

Решить поставленную задачу с помощью одного запроса достаточно сложно. Данную задачу можно разбить на две подзадачи:

1) Найти дату последней проводки или проводок по счету;

2) Вывести всю информацию о проводках за эту дату.

 

Остается только описать решение подзадач. Решение первой задачи выглядит следующим образом:

 

Select max(op.OperDate)

From tResource r

,tOperPart op

Where r.Brief = '20202840600000000000'

and op.ResourceID = r.ResourceID

 

Решение второй задачи будет следующим:

Select op.*

From tResource r

,tOperPart op

Where r.Brief = '20202840600000000000'

and op.ResourceID = r.ResourceID

and op.Operdate = дата последней проводки

 

В итоге получается решение исходной задачи:

 

Select op.*

From tResource r

,tOperPart op

Where r.Brief = '20202840600000000000'

and op.ResourceID = r.ResourceID

and op.Operdate = (Select max(op.OperDate)

From tResource r

,tOperPart op

Where r.Brief = '20202840600000000000'

and op.ResourceID = r.ResourceID )

 

Варианты использования подзапросов:

 

1) Сравнение с результатом подчиненного запроса

Значение выражения сравнивается со значением, которое возвращается вложенным запросом, и если условие сравнения выполняется, то проверка дает результат TRUE. Эта проверка используется для сравнения значения из проверяемой строки с одним значением, полученным от вложенного запроса. В операции сравнения с результатом вложенного запроса можно задействовать те же шесть операторов сравнения (=, <>, <, <=, >, >=), что и при простом сравнении. Вложенный запрос, участвующий в операции сравнения, должен возвращать в качестве результата единичное значение, то есть одну строку, содержащую один столбец. Если результатом вложенного запроса являются несколько строк или несколько столбцов, то сравнение не имеет смысла и СУБД выдаст сообщение об ошибке. Если в результате выполнения вложенного запроса не будет получено ни одной строки или будет получено значение NULL, то операция сравнения вернет NULL.

 

2) Проверка на принадлежность результатам подчиненного запроса

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

Аналогичным образом работает команда выборки с подзапросом с использованием оператора ANY. Например:

 

Select *

From table1

Where b = ANY (select b

from table 2)

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

Если необходимо, чтобы выводимые внешним запросом данные удовлетворяли всем значениям подзапроса в соответствии с указанным условием, то вместо оператора ANY используется оператор ALL.

 

3) Проверка на существование

В результате проверки на существование (предикат EXISTS) можно выяснить, содержится ли в таблице результатов вложенного запроса хотя бы одна строка. Аналогичной простой проверки не существует. Такое выражение считается истинным только тогда, когда результат вычисления "SELECT * FROM ..." является непустым множеством, т.е. когда существует какая-либо запись в таблице, указанной во фразе FROM подзапроса, которая удовлетворяет условию WHERE подзапроса. В случаях, когда необходимо сделать условие истинным при полученном пустом множестве вложенного запроса, можно использовать конструкцию NOT EXISTS. В подзапрос можно передавать значения столбцов таблиц внешнего запроса. Например:

 

Select *

From table1

Where EXISTS (select *

from table 2

where table1.a = table2.c)