Часто невозможно решить поставленную задачу путем использования одного запроса. Это особенно актуально в тех случаях, когда при использовании условия поиска в предложении WHERE
Сравниваемое значение> <оператор> <значение, с которым сравнивать>
значение, с которым надо сравнивать, заранее не определено и должно быть вычислено в момент выполнения оператора SELECT. Другой причиной использования вложенных подзапросов, является то, что во многих случаях значение, с которым надо сравнивать, должно представлять собой не одно, а несколько значений.
В общем случае оператор SELECT с подзапросом имеет вид
SELECT...
FROM...
WHERE Сравниваемое значение> <оператор> (SELECT... FROM... WHERE...)
Пример. Выдать все даты, на которые приходится максимальный отпуск товаров
SELECT KOLVO, DAT_RASH FROM RASHOD
WHERE KOLVO = (SELECT MAX(KOLVO) FROM RASHOD)
Сначала будет найдено максимальное количество отпуска товаров, поскольку это значение заранее неизвестно. Это и делает внутренний подзапрос.
Далее выполняется основной запрос.
Пример. Усложним предыдущий пример. Определить дату, когда со склада было отгружено максимальное количество товара, и реквизиты покупателя, который этот товар купил
|
|
SELECT R.KOLVO, R.DAT_RASH, P.POKUP, P.GOROD, P.ADRES
FROM RASHOD R, POKUPATELI P
WHERE (R.POKUP = P.POKUP) AND
KOLVO =(SELECT MAX(KOLVO) FROM RASHOD)
По сравнению с предыдущим примером в запрос включено внутреннее соединение таблиц RASHOD и POKUPATELI.
Пример. Составить список отгрузки товаров покупателю, который в свое время купил максимальную партию какого-либо товара
SELECT RRR.* FROM RASHOD RRR
WHERE RRR.POKUP IN (SELECT R.POKUP FROM RASHOD R
WHERE KOLVO = (SELECT MAX(RSH.KOLVO) FROM RASHOD RSH))
ЗАМЕЧАНИЕ. IN использован вместо знака равенства на тот случай, если встретится два и более покупателя, имеющие одинаковое число максимальных покупок. В этом случае запрос вернет записи из RASHOD по всем таким покупателям.
Логический порядок выполнения запроса. Вычисляется максимальное значение в столбце KOLVO ("самый вложенный" подзапрос SELECT MAX). Далее в "среднем" подзапросе SELECT R.POKUP выбирается покупатель, купивший какой-либо товар в количестве, равном значению, вычисленному в "самом вложенном" подзапросе. Вслед за этим "самый главный" запрос SELECT RRR выбирает записи с покупателем, наименование которого выдано "средним" подзапросом.
ЗАМЕЧАНИЕ. Поставленную задачу могут выполнить и другие запросы, например:
SELECT RRR.* FROM RASHOD RRR WHERE RRR.POKUP IN
(SELECT R.POKUP FROM RASHOD R GROUP BY R.POKUP
HAVING MAX(R.KOLVO) = (SELECT MAX(RSH.KOLVO) FROM RASHOD RSH))