Иллюстрированный самоучитель по SQL для начинающих

Использование вложенных запросов

Подзапрос в предложении WHERE работает точно так же, как оператор SELECT или UPDATE. To же самое верно для DELETE или INSERT. Чтобы удалить записи обо всех сделках Olympic Sales, используйте такой оператор:

DELETE TRANSMASTER
WHERE CUSTID =
(SELECT CUSTID
FROM CUSTOMER
WHERE COMPANY = 'Olympic Sales');

Как и в случае с UPDATE, подзапросы DELETE также могут быть коррелированными и также могут обращаться к изменяемой таблице (у которой в данном случае удаляют строки). Здесь действуют правила, похожие на те, что используются для подзапросов оператора UPDATE. Предположим, вы хотите удалить из таблицы CUSTOMER все строки тех пользователей, для которых итог NET_AMOUNT больше 10000 долларов:

DELETE TRANSMASTER TM1
WHERE 10000 < (SELECT SUM(NET_AMOUNT))
FROM TRANSMASTER TM2
WHERE TM1.CUSTID = TM2.CUSTID);

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

При обновлении, удалении или вставке записей базы данных есть риск сделать так, что данные в изменяемой таблице не будут соответствовать данным в других таблицах из этой базы. Такое несоответствие называется аномалией изменения (см. главу 5). Если из таблицы TRANSMASTER удаляются записи, а от нее зависит другая таблица, TRANSDETAIL (подробности сделок), то записи, соответствующие удаленным записям из первой таблицы, необходимо удалять и из второй. Эта операция называется каскадным удалением, поскольку удаление родительской записи должно вызывать каскад удалений связанных с ней дочерних записей. В противном случае неудаленные дочерние записи становятся "записями-призраками".

В операторе INSERT может находиться предложение SELECT. Такие операторы применяются для заполнения таблиц с текущей информацией. Ниже приведен запрос для создания таблицы с содержимым TRANSMASTER за 27 октября.

CREATE TABLE TRANSMASTER_1027
(TRANSID INTEGER, TRANSDATE DATE,
…);
INSERT INTO TRANSMASTER_1027
(SELECT * FROM TRANSMASTER
WHERE TRANSDATE = 2000-10-27);

Если требуется информация лишь о крупных сделках, то запрос будет таким:

INSERT INTO TRANSMASTER_102 7
(SELECT * FROM TRANSMASTER TM
WHERE TM.NET_AMOUNT > 10000
AND TRANSDATE 2000-10-27);
Если Вы заметили ошибку, выделите, пожалуйста, необходимый текст и нажмите CTRL + Enter, чтобы сообщить об этом редактору.