
пдф-Sql_All
.pdf
Нельзя одновременно всписке вывода использовать значения столбцов и агрегатные функции.!!!
В списке вывода могут присутствовать выражения из агрегатных функций
Select MAX(Mark)-Min(mark) from Sessia
Агрегатные функции могут быть применены к выражению
Select Max(A1-A2) from R1
Select SUM(A1-A2)
Это будет отлично от значения
Select SUM(A1) - SUM(A2) from R2
Функция COUNT(имя столбца) вычисляет количество ненулевых значений в столбце
Агрегатная функция не может быть аргументом другой агрегатной функции!!!
Поэтому нельзя вкладывать агрегатные функции !!!
Внешние объединения.
Стандарт SQL2 расширил понятие условного объединения. В стандарте SQL1, при объединении отношений использовались только условия, задаваемые в части WHERE оператора SELECT, и в этом случае в результирующее отношение попадпли только сцепленные по заданным условиям кортежи исходных отношений, для которых эти условия были определены и истинны. Однако в действительности часто необходимо объединять таблицы таким образом, что бы в результат попали все строки из первой таблицы, а вместо тех строк второй
таблицы, для которых не выполнено условие соединения в результат попадали бы неопределенные значения. Или наоборот, включаются все стороки из правой (второй) таблицы, а из неудовлетворяющие части строк из первой таблицы дополняются неопределенными значениями. Такие объединения были названы внешними в противоположность объединениям, определенным стандартом SQL1, которые стали называться внутренними.
В общем случае синтаксическая диаграмма части FROM в стандарте SQL2 выглядит следующим образом:
Выражение естественного объединения:
| Таблица 1 NATURAL JOIN Таблица 2 →•
INNER
FULL
LEFT OUTER RIGHT
Выражение перекрестного объединения Фактически это полное декартово произведение таблицы1 и таблицы 2.
Выражение запроса на объединение
| Табл. 1 JOIN Табл. 2 ON условие
→•
INNER |
USING (список |
столбцов)
FULL
LEFT OUTER RIGHT
Выражение объединения
Эта операция соответствует операции теоретико множественного объединения в алгебре, поэтому для нее естественым ограничением является наличие эквивалентных схем.
В этих диаграммах INNER – означает внутреннее объединение, LEFT – левое объединение, т.е. в результат входят все строки Табл. 1 , а неопределенные значения для табл.2 дополняются значениями NULL, RIGHT – наоборот, а FULL – полное внешние объединение и левое и правое. Ключевое слово OUTER означает внешнее, но если заданы ключевые слова FULL, LEFT, RIGHT , то объединение всегда считается внешним.
Рассмотрим примеры выполнения внешних объединений на примере БД «Библиотека»
BOOKS( ISBN,TITL,AUTOR,COAUTOR,YEARIZD,PAGES)
READER( NUM_READER, NAME_READER, ADRES, HOOM_PHONE, WORK_PHONE, BIRTH_DAY)
EXEMPLARE( INV,ISBN,YES_NO,NUM_READER,DATE_IN,DATE_O UT)
Определим перечень книг у каждого читателя, если у читателя нет книг, то номер экзекмпляра книги равен NULL. Для выполнения этого поиска нам надо выполнить левое внешнее объединение, т.е. мы берем все строки из таблицы READER и соединяем со строками из таблицы EXEMPLARE, если во второй таблице нет строки с соотвествующим номером читательского билета, то в строке результирующего отношения атрибут EXEMPLARE.INV будет иметь неопределенное значение NULL:
SELECT READER.NAME_READER, EXEMPLARE.INV FROM READER RIGHT JOIN EXEMPLARE ON READER.NUM_READER=EXEMPLARE.NUM_READER
Операция внешнего объединения может использоваться для формирования источников в предложении FROM, поэтому допустимым будет например следующий текст запроса:
SELECT *
FROM ( BOOKS LEFT JOIN EXEMPLARE) LEFT JOIN
(READER NATURAL JOIN EXEMPLARE) USING (ISBN)
При этом для книг, ни один экземпляр которых не находится на руках у читателей значения номера читательского билета и дат взятия и возврата книги будут неопределенными.

П е р е к р е с т н о е о бъ ед и н е н и е с о от в е т с т вуе т о п е р а ц и и расширенного декартова произведения.
3.4. Объединение (UNION)
В алгебре рассматривалась реляционная операция "Объединение", позволяющая получить отношение, состоящее из всех строк, входящих в одно или оба объединяемых отношения. Но при этом исходные отношения или их объединяемые проекции должны быть совместимыми по объединению. Для SQL это означает, что две таблицы можно объединять тогда и только тогда, когда:
-они имеют одинаковое число столбцов, например, m;
-для всех i (i = 1, 2, ..., m) i-й столбец первой таблицы и i-й столбец второй таблицы имеют в точности одинаковый тип данных.
Например, выдать названия продуктов, в которых нет жиров, либо входящих в состав блюда с кодом БЛ = 1:
Результат: Продукт
SELECTПродукт
FROMПродукты
WHEREЖиры = 0
UNION
SELECTПродукт
FROMСоста
WHEREБЛ = 1
Майонез
Лук
Помидоры
Зелень
Яблоки Сахар
Из этого простого примера видно, что избыточные дубликаты всегда исключаются из результата UNION. Поэтому, хотя в рассматриваемом примере Помидоры, Зелень и Яблоки выбираются обеими из двух составляющих предложения SELECT, в окончательном результате они появляются только один раз.
Предложением с UNION можно объединить любое число таблиц (проекций таблиц). Так, к предыдущему запросу можно добавить (перед точкой с запятой) конструкцию
UNION
SELECTПродукт
FROMПродукты
WHERE Ca < 250
позволяющую добавить к списку продуктов Масло, Рис, Мука и Кофе. Однако тот же результат можно получить простым изменением фразы WHERE первой части исходного запроса
WHERE Жиры = 0 OR Ca < 250
4.2. Предложение DELETE
4.2.1. Удаление единственной записи Удалить поставщика с ПС = 7.
DELETE
FROM Поставщики
WHERE ПС = 7;
Если таблица Поставки содержит в момент выполнения этого предложения какие-либо поставки для поставщика с ПС = 7, то такое удаление нарушит непротиворечивость базы данных. К сожалению нет операции удаления, одновременно воздействующей на несколько таблиц. Однако в некоторых СУБД реализованы механизмы поддержания целостности (см.п.2.5 в литературе [2]), позволяющие отменить некорректное удаление или каскадировать удаление на несколько таблиц.
Удаление множества записей
Удалить все поставки.
DELETE
FROMПоставки;
Поставки - все еще известная таблица, но в ней теперь нет строк. Для уничтожения таблицы надо выполнить операцию DROP TABLE Поставки (см.п.5.2).
Удалить все мясные блюда.
DELETE FROM Блюда
WHERE Основа = 'Мясо';
Удаление с вложенным подзапросом
Удалить все поставки для поставщика из Паневежиса.
DELETE FROMПоставки
WHEREПС IN (SELECT ПС
FROM Поставщики
WHERE Город = 'Паневежис');
4.3.Предложение INSERT
4.3.1.Вставка единственной записи в таблицу
Синтаксическая диаграмма операции INSERT представлена на рис.
Добавить в таблицу Блюда блюдо:
Шашлык (БЛ - 34, Блюдо - Шашлык, В - Г, Основа - Мясо, Выход - 150) при неизвестной пока трудоемкости приготовления этого
блюда.
INSERT
INTOБлюда (БЛ, Блюдо, В, Основа, Выход)
VALUES (34, 'Шашлык', 'Г', 'Мясо', 150);
Создается новая запись для блюда с номером 34, с неопределенным значением в столбце Труд.
Порядок полей в INSERT не обязательно должен совпадать
с порядком полей, в котором они определялись при создании таблицы. Вполне допустима и такая версия предыдущего предложения:
INSERT
INTOБлюда (Основа, В, Блюдо, БЛ, Выход)
VALUES ('Мясо', 'Г', 'Шашлык', 34, 150);
При известной трудоемкости приготовления шашлыка (например, 5 коп) сведения о нем можно ввести с помощью укороченного предложения:
INSERT INTOБлюда
VALUES (34, 'Шашлык', 'Г', 'Мясо', 150, 5);
в котором должен соблюдаться строгий порядок перечисления вводимых значений, так как, не имея перечня загружаемых столб-цов, СУБД может использовать лишь перечень, который определен при создании модифицируемой таблицы.
В предыдущих примерах проводилась модификация стержневой сущности, т.е. таблицы с первичным ключом БЛ (см.п.2.4 в лите-ратуре [2]). Почти все СУБД имеют механизмы для предотвращения ввода не уникального первичного ключа, например, ввода "Шашлыка" под номером, меньшим 34. А как быть с ассоциациями или другими таблицами, содержащими внешние ключи?
Пусть, например, потребовалось добавить в рецепт блюда Салат летний (БЛ = 1) немного (15 г) лука (ПР = 10), и мы воспользовались предложением
INSERT
INTOСостав (БЛ, ПР, Вес)
VALUES (1, 10, 15);
Подобно операции DELETE операция INSERT может нарушить непротиворечивость базы данных. Если не принять специальных мер, то СУБД не проверяет, имеется ли в таблице Блюда блюдо с первичным ключом БЛ = 1 и в таблице Продукты - продукт с первичным ключом ПР = 10. Отсутствие любого из этих значений породит противоречие: в базе появится ссылка на несуществующую запись. Проблемы, возникающие при использовании внешних ключей, подробно рассмотрены в литературе [2], а здесь отме-тим, что все "приличные" СУБД имеют механизмы для предотв-ращения ввода

записей со значениями внешних ключей, отсутст-вующих среди значений соответствующих первичных ключей.
Предложение UPDATE
Обновление единственной записи Изменить название блюда с кодом БЛ=5 на Форшмак,
увеличить его выход на 30 г и установить NULL-значение в столбец Труд.
UPDATE Блюда
SETБлюдо = 'Форшмак', Выход = (Выход+30), Труд = NULL WHERE БЛ = 5;
Обновление множества записей
Утроить цену всех продуктов таблицы поставки (кроме цены кофе - ПР = 17).
UPDATE Поставки
SETЦена = Цена * 3
WHERE ПР <> 17;
Обновление с подзапросом
Установить равной нулю цену и К_во продуктов для поставщиков из Паневежиса и Резекне.
UPDATE Поставки
SETЦена = 0, К_во = 0 WHERE ПС IN
(SELECT ПС
FROMПоставщики
WHERE Город IN ('Паневежис', 'Резекне'));
4.4.4. Обновление нескольких таблиц Изменить номер продукта ПР = 13 на ПР = 20.
UPDATE |
Продукты |
UPDATE |
Состав |
SET |
ПР = 20 |
SET |
ПР = 20 |
WHERE |
ПР = 13; |
WHERE |
ПР = 13; |

UPDATE |
Поставки |
UPDATE |
Наличие |
SET |
ПР = 20 |
SET |
ПР = 20 |
WHERE |
ПР = 13; |
WHERE |
ПР = 13; |
К сожалению, в единственным запросе невозможно обновить более одной таблицы, а так как код продукта входит в четыре таблицы, то пришлось выдать четыре сходных запроса. Это может привести к противоречию базы данных (нарушению целостности по ссылкам), поскольку после выполнения первого предложения таблицы Состав, Поставки и Наличие ссылаются на уже несуществующий продукт. База становится непротиворечивой только после выполнения четвертого запроса.
О конструировании предложений модификации
Для тех, кто достаточно хорошо понял предложение SELECT, несложно овладеть конструированием предложений DELETE, INSERT и UPDATE. Но в процессе такого конструирования следует учитывать, что:
Во вложенном подзапросе в операциях модификации данных в предложении FROM не должна упоминаться модифицируемая таблица!!!
Если в WHERE фразе предложений DELETE и UPDATE используется вложенный подзапрос, то во фразе FROM этого подзапроса не должна упоминаться таблица, из которой удаляются (в которой обновляются) строки. Аналогично, в подзапросе предложения INSERT не должна упоминаться таблица, в которую загружаются данные.
Так, SQL отвергнет предложение
INSERT
INTO Выбрано
SELECT |
(33), Т, БЛ |
FROM |
Выбрано |
WHEREСМ = 17;
позволяющее ввести информацию о том, что отдыхающий, сидящий на 33-м месте, выбирает тот же набор блюд, что и отдыхающий, сидящий на 17-м месте. Ввод придется осуществить через какую-либо промежуточную таблицу, например, таблицу Выбор:
DELETE
FROMВыбор;
INSERT
INTOВыбор (СМ, Т, БЛ)
SELECT (33), Т, БЛ
FROMВыбрано
WHEREСМ = 17;
INSERT INTOВыбрано
SELECTСМ, Т, БЛ FROMВыбор;
2. Составляя предложения модификации данных, необходимо все время помнить о сохранении непротиворечивости базы данных. Об этом упоминалось ранее и подробно говорилось в литературе [2].
Декартово
Внешние объединения
2.4.1 Оператор определения схемы
В соответствии с правилами SQL/89 каждая таблица данной БД имеет простое и квалифицированное (уточненное) имена. В качестве квалификатора имени выступает “идентификатор полномочий” таблицы, который обычно в реализациях совпадает с именем некоторого пользователя. Квалифицированное имя таблицы имеет вид:
<идентификатор полномочий>.<простое имя>
Подход к определению схемы в SQL/89 состоит в том, что все таблицы