Программирование >>  Построение запросов sql 

1 ... 62 63 64 [ 65 ] 66 67 68 ... 101


Подзапрос, использованный в данном запросе UPDATE, является связанным, так как в нем используется поле AccountCD внешней обновляемой таблицы (условие R.AccountCD = N.AccountCD). При выполнении обновления сначала выбирается строка из таблицы NachislSumma, затем выполняется вложенный запрос, возвращая количество ремонтных заявок для выбранного абонента, а уже затем, в случае удовлетворения условию в предложении WHERE запроса UPDATE, происходит обновление текущей строки таблицы NachislSumma. Обновление происходит последовательно для каждой строки таблицы NachislSumma без возврата к извлечению уже просмотренных строк.

Приведем еще один пример с использованием соотнесенного вложенного запроса. Путь требуется уменьшить на 10 руб. суммы, начисленные за сентябрь 2001, абонентам, заплатившим до 15 сентября 2001 года за август 2001 (произвели оплату за август 2001 до 15.09.2001) сумму, меньше средней суммы всех своих платежей. Для решения этой задачи можно использовать следующий запрос:

UPDATE NachislSumma SET NachislSum = NachislSum - 10 WHERE NachislYear = 2001 AND NachislMonth = 9 AND AccountCD IN

(SELECT AccountCD

FROM PaySumma A

WHERE PayYear = 2001 AND PayMonth = 8 AND PayDate < 15.09.2001 AND PaySum <

(SELECT AVG(PaySum) FROM PaySumma B

GROUP BY AccountCD

HAVING A.AccountCD = B.AccountCD));.

Фрагмент таблицы NachislSumma после обновления представлен на рис. 5.4.

NACHISLFACTCD

ACCOUNTCD

GAZSERVICECD

NACHISLSUM

NACHISLMONTH

NACHISLYEAR

115705

240,00

2001

443069

70,00

2001

443069

28,32

2001

Рис. 5.4. Содержание таблицы NachislSumma после обновления

В предложении FROM подзапроса в запросе UPDATE может присутствовать имя обновляемой таблицы. В этом случае предполагается, что используется то состояние обновляемой таблицы, которое она имела до обновления.

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



UPDATE NachislSumma SET NachislSum = NachislSum / 2 WHERE NachislSum > (SELECT AVG (NachislSum)

FROM NachislSumma WHERE NachislMonth = 12 AND

NachislYear = 2001 AND GazServiceCD=2) AND GazServiceCD=2;.

Фрагмент таблицы NachislSumma после обновления представлен на рис. 5.5.

NACHISLFACTCD

ACCOUNTCD

GAZSERVICECD

NACHISLSUM

NACHISLMONTH

NACHISLYEAR

005488

29,35

2001

005488

28,00

1999

115705

125,00

2001

136160

28,00

1999

080047

40,00

1998

080047

40,00

2001

080613

28,00

2001

115705

125,00

2000

115705

29,35

2001

136169

29,35

2001

443069

40,00

2001

Рис. 5.5. Таблица NachislSumma после обновления

В предыдущем примере использован вложенный запрос, который был успешно выполнен. Это произошло потому, что сначала один раз выполнился вложенный запрос, возвратив среднее значение сумм начислений за декабрь 2001 года, а затем произошло обновление таблицы NachislSumma. В результате выполнения запроса в таблице NachislSumma 11 записей были обновлены.

Аналогично возможно использование соотнесенного вложенного запроса, относящегося к той же самой таблице, которая указана в качестве обновляемой. Рассмотрим пример такого соотнесенного подзапроса в предложении SET. Например, для замены дат выполнения ремонтных заявок, относящихся к каждому абоненту, на наиболее позднюю дату их регистрации можно использовать следующий запрос:

UPDATE Request

SET ExecutionDate =

(SELECT MAX (R.IncomingDate) FROM Request R WHERE R.AccountCD = Request.AccountCD);.

Таблица Request после обновления представлена на рис. 5.6.



REQUESTCD

ACCOUNTCD

EXECUTORCD

FAILURECD

INCOMINGDATE

EXECUTIONDATE

EXECUTED

005488

17.12.2001

17.12.2001

115705

07.08.2001

28.12.2001

015527

28.02.1998

28.02.1998

080270

31.12.2001

31.12.2001

080613

16.06.2001

16.06.2001

080047

20.10.1998

11.10.2001

136169

06.11.2001

06.11.2001

136159

01.04.2001

01.04.2001

136160

12.01.1999

18.05.2001

443069

08.08.2001

13.09.2001

005488

04.09.2000

17.12.2001

005488

04.04.1999

17.12.2001

115705

20.09.2000

28.12.2001

115705

28.12.2001

28.12.2001

115705

15.08.2001

28.12.2001

115705

28.12.1999

28.12.2001

080270

17.12.2001

31.12.2001

080047

11.10.2001

11.10.2001

443069

13.09.2001

13.09.2001

136160

18.05.2001

18.05.2001

136169

07.05.2001

06.11.2001

Рис. 5.6. Таблица Request после обновления

После выполнения обновления у каждого абонента стала одинаковой дата выполнения всех ремонтных заявок (она стала совпадать с датой поступления последней заявки, поданной этим абонентом). Например, от абонента с номером лицевого счета 005488 поступило 3 ремонтных заявки: первая -04.04.1999, вторая - 04.09.2000 и последняя - 17.12.2001. Дата выполнения всех трех заявок после выполнения запроса стала равной 17.12.2001.

5.3. Обобщенное обновление и добавление данных

Помимо запросов UPDATE и INSERT существует обобщенный запрос UPDATE OR INSERT, который предоставляет возможность изменять или вставлять запись в зависимости от того, существует она в целевой таблице или нет. Такой запрос имеет следующий синтаксис:

UPDATE OR INSERT INTO { базовая таблица представление} [(<список столбцов>); VALUES ({константа1 переменная1} [, {константа2 переменная2}] ...) [MATCHING <список столбцов>]

RETURNING <список столбцов> [INTO <список переменных>]];.

Например, требуется добавить исполнителя ПЕТРОВ А.С. с кодом 1, причем если исполнитель с таким кодом уже существует, то следует изменить его ФИО на ПЕТРОВ А.С. Запрос будет выглядеть следующим образом:

UPDATE OR INSERT INTO Executor VALUES (1,ПЕТРОВ А.С.);.

Результат выполнения запроса представлен на рис. 5.7.



1 ... 62 63 64 [ 65 ] 66 67 68 ... 101

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика