Delphi 3 и создание приложений баз данных

         

Использование подзапросов


Часто невозможно решить поставленную задачу путем использования одного запроса. Это особенно актуально в тех случаях, когда при использовании условия поиска в предложении WHERE

Сравниваемое значение> <оператор> <значение, с которым сравнивать>

значение, с которым надо сравнивать,

заранее не определено и должно быть вычислено в момент выполнения оператора SELECT.

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

Внутренний подзапрос представляет собой также оператор SELECT и кодирование его предложений подчиняется тем же правилам, что и для основного оператора SELECT.

В общем случае оператор SELECT с подзапросом имеет вид

SELECT .. .

FROM ...

WHERE Сравниваемое значение> <оператор> SELECT ...

FROM ...

WHERE ...

Пример.

Выдать все даты, на которые приходится максимальный отпуск товаров (результат на рис. 25.36).

SELECT KOLVO, DAT_RASH FROM RASHOD

WHERE KOLVO = (SELECT MAX(KOLVO) FROM RASHOD

KOLVO

DAT_RASH

1

10.01.97

Puc. 25.36.

Сначала нужно найти количество максимального отпуска товаров, поскольку это значение неизвестно. Это и делает внутренний подзапрос (SELECT MAX(KOLVO) FROM RASHOD )

Далее выполняется основной запрос, как если бы он был записан так:

SELECT KOLVO, DAT_RASH FROM RASHOD WHERE KOLVO = 4000

Пример.

Усложним предыдущий пример. Определить дату, когда со склада было отгружено максимальное количество товара, и реквизиты покупателя, который этот товар купил (результат на рис. 25.37).

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, который вместо единичного значения способен возвращать список значений.

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

Пример.

Найти в таблице POKUPATELI покупателя, у которого поле GOROD содержит "С-Петербург" и выдать все осуществленные им покупки товаров, из таблицы RASHOD. Может быть написан следующий потенциально ошибочный запрос (результат на рис. 25.38).

SELECT R.DAT_RASH, R.TOVAR, R.KOLVO, R.POKUP FROM RASHOD R

WHERE R.POKUP = (SELECT POK.POKUP FROM POKUPATELI РОК

WHERE UPPER(РОК.GOROD) = 'С-ПЕТЕРБУРГ '

)

Хотя для значения "С-Петербург" и был выдан корректный результат, такой запрос потенциально ошибочен, поскольку способен возвращать несколько значений; например, если поменять "С-Петербург" на "Москва", получим уведомление об ошибке (рис. 25.39)

SELECT R.DAT_RASH, R.TOVAR, R.KOLVO, R.POKUP FROM RASHOD R

WHERE R.POKUP = (SELECT POK.POKUP FROM POKUPATELI РОК

WHERE UPPER(РОК.GOROD) = 'МОСКВА' )



Содержание раздела