Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

пдф-Sql_All

.pdf
Скачиваний:
15
Добавлен:
14.04.2015
Размер:
403.87 Кб
Скачать

Нельзя одновременно всписке вывода использовать значения столбцов и агрегатные функции.!!!

В списке вывода могут присутствовать выражения из агрегатных функций

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 состоит в том, что все таблицы