
Введение в язык SQL
В этом разделе мы рассмотрим назначение языка SQL, познакомимся с его историей и проанализируем причины, по которым он приобрел в настоящее время столь большое значение для приложений баз данных.
Назначение языка SQL
Любой язык работы с базами данных должен предоставлять пользователю следующие возможности:
• создавать базы данных и таблицы с полным описанием их структуры;
• выполнять основные операции манипулирования данными, такие как
вставка, модификация и удаление данных из таблиц;
• выполнять простые и сложные запросы.
Кроме того, язык работы с базами данных должен решать все указанные выше задачи при минимальных усилиях со стороны пользователя, а структура и синтаксис его команд должны эыть достаточно просты и доступны для изучения. И, наконец, он должен быть универсальным, т.е. отвечать некоторому признанному стандарту, что позволит использовать один и тот же синтаксис иструктуру команд при переходе от одной СУБД к другой. Язык SQL удовлетворяет практически всем этим требованиям.
SQL является примером языка преобразования данных, или же языка, предназначенного для работы с таблицами с целью преобразования входных данных к требуемому выходному виду. Язык SQL, который определен стандартом ISO, имеет два основных компонента:
• язык DDL (Data Definition Language), предназначенный для определения
структур базы данных и управления доступом к данным;
• язык DML (Data Manipulation Language), предназначенный для выборки и обновления данных.
До появления стандарта SQL3 язык SQL включал только команды определения и манипулирования данными; в нем отсутствовали какие-либо команды управления ходом вычислений. Другими словами, в этом языке не было команд IF ... THEN ...ELSE, GO TO, DO ... WHILE и любых других, предназначенных для управления ходом вычислительного процесса. Подобные задачи должны были решаться программным путем (с помощью языков программирования или управления заданиями) либо интерактивно (в результате действий, выполняемых самим пользователем). По причине
подобной незавершенности (с точки зрения организации вычислительного процесса) язык SQL мог использоваться двумя способами. Первый предусматривал интерактивную работу, заключающуюся во вводе пользователем с терминала отдельных операторов SQL. Второй состоял во внедрении операторов SQL в программы на процедурных языках, как описано в главе 21. Язык SQL3, формальное определение которого принято в 1999 году, рассматривается в главе 27.
Язык SQL относительно прост в изучении.
• Это непроцедурный язык, поэтому в нем необходимо указывать, какая информация должна быть получена, а не как ее можно получить. Иначе говоря, язык SQL не требует указания методов доступа к данным,
• Как и большинство современных языков, SQL поддерживает свободный формат записи операторов. Это означает, что при вводе отдельные элементы операторов не связаны с фиксированными позициями на экране.
• Структура команд задается набором ключевых слов, представляющих собой
обычные слова английского языка, такие как CREATE TABLE (Создать таблицу), INSERT (Вставить), SELECT (Выбрать). Например:
• CREATE TABLE Staff (staffNo VARCHAR(S), IName VARCHAR(15),salary DECIMAL(7,2));
• INSERT INTO Staff VALUES ('SG16', 'Brown', 8300);
• SELECT staffNo, IName, salary
FROM Staff
WHERE salary > 10000;
• Язык SQL может использоваться широким кругом пользователей, включая администраторов баз данных (АБД), руководящий персонал компании, прикладных программистов и множество других конечных пользователей разных категорий.
В настоящее время для языка SQL существуют международные стандарты [173],[176], формально определяющие его как стандартный язык создания и манипулирования реляционными базами данных, каковым он фактически и является.
Особая роль языка SQL
Язык SQL является первым и пока единственным стандартным языком работы с базами данных, который получил достаточно широкое распространение.
Есть еще один стандартный язык работы с базами данных, NDL (Network
Database Language), который построен на использовании сетевой модели CODASYL, но он применяется лишь в немногих разработках. Практически все крупнейшие разработчики СУБД в настоящее время создают свои продукты с использованием языка SQL либо интерфейса SQL, и большинство таких компаний участвуют в работе, по меньшей мере, одной организации, которая занимается разработкой стандартов этого языка. В SQL сделаны огромные инвестиции как со стороны разработчиков, так и со стороны пользователей. Он стал частью архитектуры приложений (например, такой как System Application Architecture(SAA) корпорации IBM), а также является стратегическим выбором многих крупных и влиятельных организаций (например, консорциума Х/Open, занятого разработкой стандартов для среды UNIX), Язык SQL также принят в качестве федерального стандарта обработки информации (Federal Information Processing Standard — FIPS), который должен соблюдаться в СУБД для получения разрешения продавать ее на территории США. Консорциум разработчиков SQL Access Group прилагает усилия по созданию расширений языка SQL, которые позволят обеспечить взаимодействие разнородных систем.
Запись операторов SQL
В этом разделе кратко описана структура операторов SQL и представлена система обозначений, которая используется для определения формата различных конструкций языка SQL. Оператор SQL состоит из зарезервированных слов, а также из слов, определяемых пользователем. Зарезервированные слова являются постоянной частью языка SQL и имеют определенное значение. Их следует записывать именно так, как указано в стандарте, и нельзя разбивать на части для переноса из одной строки в другую. Слова, определяемые пользователем, задаются самим пользователем (в соответствии с определенными синтаксическими правилами) и представляют собой имена различных объектов базы данных —таблиц, столбцов, представлений, индексов и т.д. Слова в операторе размещаются в соответствии с установленными синтаксическими правилами. Хотя в стандарте это не указано, многие диалекты языка SQL требуют задания в конце оператора некоторого символа, обозначающего окончание его текста; как правило, с этой целью используется точка с запятой (;).
Большинство компонентов операторов SQL не чувствительно к регистру. Это означает, что могут использоваться любые буквы — как строчные, так и прописные. Одним важным исключением из этого правила являются символьные литералы — данные, которые должны вводиться точно так же, как были введены соответствующие им значения, хранящиеся в базе данных. Например, если в базе данных хранится значение фамилии 'SMITH1 , а в условии поиска указан символьный литерал ' Smith1 , то эта запись не будет найдена.
Поскольку язык SQL имеет свободный формат, отдельные операторы SQL и их оследовательности будут иметь более удобный для чтения вид при использовании отступов и выравнивания. Рекомендуется придерживаться следующих правил.
• Каждая конструкция в операторе должна начинаться с новой строки.
• Начало каждой конструкции должно быть обозначено таким же отступом, что и начало других конструкций оператора.
• Если конструкция состой-:: из нескольких частей, каждая из них должна начинаться с новой строки с некоторым отступом относительно начала конструкции, что будет указывать на их подчиненность.
В этой и следующей главе для определения формата операторов SQL мы будем применять следующую расширенную форму системы обозначений BNF(Backus Naur Form — форма Бэкуса-Наура).
• Прописные буквы будут использоваться для записи зарезервированных слов и должны указываться в операторах точно так же, как это будет показано.
• Строчные буквы будут использоваться для записи слов, определяемых пользователем.
• Вертикальная черта ( ) указывает на необходимость выбора одного из нескольких приведенных значений, например a b | с.
• Фигурные скобки определяют обязательный элемент, например {а}.
• Квадратные скобки определяют необязательный элемент, например [а].
• Многоточие (...) используется для указания необязательной возможностиповторения конструкции от нуля до нескольких раз, например
{а Ь} [,с...]. Эта запись означает, что после а или Ь может следовать от нуля до нескольких повторений с, разделенных запятыми.
На практике для определения структуры базы данных (в основном ее таблиц)используются операторы DDL, а для заполнения этих таблиц данными и выборки из них информации с помощью запросов — операторы DML. В этой главе вначале мы познакомимся с операторами DML и лишь затем обратимся к операторам языка DDL. Подобный подход отражает большую важность операторов
DML с точки зрения рядового пользователя.
Манипулирование данными
В этом разделе обсуждаются следующие операторы языка SQL DML:
• SELECT — выборка данных из базы;
• INSERT — вставка данных в таблицу;
• UPDATE — обновление данных в таблице;
• DELETE — удаление данных из таблицы.
Ввиду сложности оператора SELECT и относительной простоты остальных операторов DML, большая часть данного раздела посвящена обсуждению возможностей оператора SELECT и его различных форматов. Начнем с рассмотрения самых простых запросов, затем перейдем к более сложным вариантам выборки данных, использующим функции сортировки, группирования≫ агрегирования, а также выполнения запроса к нескольким таблицам. В конце данной главы описаны операторы INSERT, UPDATE и DELETE языка SQL.
Для построения примеров операторов SQL используется контекст учебного приложения DreamHome. В базе данных приложения DreamHome имеются следующие таблицы:
Branch (branchNo, street, city, postcode)
Staff (sjiajE f No, fName, IName, position, sex, DOB, salary,
branchNo)
PropertyForRent (propertyNo, street, city, postcode, type, rooms,
rent, ownerNo, staffNo, branchNo}
Client (clientNo, fName, IName, telNo, prefType, maxRent)
PrivateOwner (ownerNo, fName, IName, address, telNo)
Viewing (clientNo, propertyNo, viewDate, comment)
Литералы
Прежде чем приступить к обсуждению операторов DML, необходимо выяснить, что означает такое понятие, как "литерал". Литералы представляют собой константы, которые используются в операторах SQL. Существуют различные формы литералов для каждого типа данных, которые поддерживаются SQL(Однако мы не станем углубляться в подробности и укажем лишь различия между литералами, которые следует заключать в одинарные кавычки, и теми, которые не следует. Все нечисловые значения данных всегда должны заключаться в одинарные кавычки, а все числовые данные не должны заключаться в одинарные кавычки. Ниже приведен пример использования литералов для вставки данных в таблицу.
INSERT INTO PropertyForRent(propertyNo, street, city, postcode,type,
rooms, rent, ownerNo, staffNo, ranchNo)
VALUES('PA14', 46 Holhead1, 'Aberdeen1 , 'AB7 5SU1 , 'House1 , 6,
650.00, 'C0461 , 'SA91 , ' B 0 0 7 ' ) ;
Значение столбца rooms является литералом целочисленного типа, а значение столбца rent — это десятичный числовой литерал. Ни один из них не должен заключаться в одинарные кавычки. Значения всех остальных столбцов представляют собой символьные строки и обязательно должны быть взяты в одинарные кавычки.
Простые запросы
Назначение оператора SELECT состоит в выборке и отображении данных одной или более таблиц базы данных. Это исключительно мощный оператор, способный выполнять действия, эквивалентные операторам реляционной алгебры выборки, проекции и соединения (см. раздел 4.1), причем в пределах единственной выполняемой команды. Оператор SELECT является чаще всего используемой командой языка SQL. Общий формат оператора SELECT имеет следующий вид:
SELECT [DISTINCT; [• ALL] .{ * I [columnExpression IAS newName]] [ , ' . . . ' } ' }
FROM TaJbleWame '{alias] [ , . . - ]
[WHERE condition].,
[GROUP BY columnwise] [HAVING condition]
QRDER BY columnList]
Здесь параметр columnExpression представляет собой имя столбца или выражение из нескольких имен. Параметр TableName является именем существующей в базе данных таблицы (или представления), к которой необходимо получить доступ. Необязательный параметр alias — это сокращение, устанавливаемое для имени таблицы TableName. Обработка элементов оператора SELECT
выполняется в следующей последовательности.
• FROM. Определяются имена используемой таблицы или нескольких таблиц.
• WHERE. Выполняется фильтрация строк объекта в соответствии с заданными условиями.
• GROUP BY. Образуются группы строк, имеющих одно и то же значение в указанном столбце.
• HAVING. Фильтруются группы строк объекта в соответствии с указанным условием.
• SELECT. Устанавливается, какие столбцы должны присутствовать в выходных данных.
• ORDER BY. Определяется упорядоченность результатов выполнения оператора.
Порядок конструкций в операторе SELECT не может быть изменен. Только две конструкции оператора — SELECT и FROM — являются обязательными, все остальные конструкции могут быть опущены. Операция выборки с помощью оператора SELECT является замкнутой, в том смысле, что результат запроса к таблице также представляет собой таблицу (см. раздел 4.1). Существует множество вариантов использования данного оператора, что иллюстрируется приведенными ниже примерами.
Выборка строк (конструкция WHERE)
В приведенных выше примерах в результате выполнения операторов SELECT выбирались все строки указанной таблицы. Однако очень часто требуется тем или иным образом ограничить набор строк, помещаемых в результирующую таблицу запроса. Это достигается с помощью указания в запросе конструкции WHERE. Она состоит из ключевого слова WHERE, за которым следует перечень условий поиска, определяющих те строки, которые должны быть выбраны при выполнении запроса. Существует пять основных типов условий поиска (или предикатов, если пользоваться терминологией ISO).
• Сравнение. Сравниваются результаты вычисления одного выражения с результатами вычисления другого выражения.
• Диапазон. Проверяется, попадает ли результат вычисления выражения в заданный диапазон значений.
• Принадлежность к множеству. Проверяется, принадлежит ли результат вычисления выражения к заданному множеству значений.
• Соответствие шаблону. Проверяется, отвечает ли некоторое строковое значение заданному шаблону.
• Значение NULL. Проверяется, содержит ли данный столбец NULL
(неопределенное значение).
Сортировка результатов (конструкция ORDER BY)
В общем случае строки в результирующей таблице запроса SQL не упорядоченыкаким-либо определенным образом (хотя в некоторых СУБД может быть предусмотрено применение по умолчанию определенного способа упорядочения, например по первичному ключу). Однако их можно отсортировать надлежащим образом, для чего в оператор SELECT помещается конструкция ORDER BY. Конструкция ORDER BY включает список разделенных запятыми идентификаторов столбцов, по которым требуется упорядочить результирующую таблицу запроса. Идентификатор столбца может представлять собой либо его имя, либо номер1, который обозначает элемент списка SELECT в соответствии с его позицией в этом списке. Самый левый элемент списка имеет номер 1, следующий — 2 и т.д. Номера столбцов могут использоваться в тех случаях, когда столбцы, по которым следует упорядочить результат, являются вычисляемыми, а конструкция AS с указанием имени этого столбца в операторе SELECT отсутствует. Конструкция ORDER BY позволяет упорядочить выбранные записи в порядке возрастания (ASC) или убывания (DESC)значений любого столбца или комбинации столбцов, независимо от того, присутствуют эти столбцы в таблице результатов или нет. Однако в некоторых диалектах SQL требуется, чтобы конструкция ORDER BY обязательно присутствовала в списке выборки оператора SELECT. В любом случае конструкция ORDER BY всегда должна быть последним элементом в операторе SELECT.
Использование агрегирующих функций языка SQL
Стандарт ISO содержит определение следующих пяти агрегирующих функций:
• COUNT — возвращает количество значений в указанном столбце;
• SUM — возвращает сумму значений в указанном столбце;
• AVG — возвращает усредненное значение в указанном столбце;
• MIN — возвращает минимальное значение в указанном столбце;
• МАХ — возвращает максимальное значение в указанном столбце.
.Все эти функции оперируют со значениями в единственном столбце таблицы и возвращают единственное значение. Функции COUNT, MIN и МАХ применимы как к числовым, так и к нечисловым полям, тогда как функции SUM и AVG могут использоваться только в случае числовых полей. За исключением COUNT ( * ) , при вычислении результатов любых функций сначала исключаются все пустые значения,после чего требуемая операция применяется только к оставшимся непустым значениям столбца. Вариант COUNT (*} является особым случаем использования функции COUNT — его назначение состоит в подсчете всех строк в таблице, независимо от того, содержатся там пустые, повторяющиеся или любые другие значения.
Если до применения агрегирующей функции необходимо исключить повторяющиеся значения, следует перед именем столбца в определении функции поместить ключевое слово DISTINCT. Сг'андарт ISO допускает использование ключевого слова ALL с целью явного указания того, что исключение повторяющихся значений не требуется, хотя это ключевое слово подразумевается по умолчанию, если никакие иные определители не заданы. Ключевое слово DISTINCT не имеет смысла для функций MIN и МАХ. Однако его использование может оказывать влияние на результаты выполнения функций SUM и AVG, поэтому следует заранее обдумать, должно ли оно присутствовать в каждом конкретном случае. Кроме того, ключевое слово DISTINCT в каждом запросе может быть указано не более одного раза.
Следует отметить, что агрегирующие функции могут использоваться только в списке выборки SELECT и в конструкции HAVING (см. раздел 5.3.4). Во всех других случаях применение этих функций недопустимо. Если список выборки SELECT содержит агрегирующую функцию, а в тексте запроса отсутствует конструкция GROUP BY, обеспечивающая объединение данных в группы (см. раздел 5.3.4), то ни один из элементов списка выборки SELECT не может включать каких-либо ссылок на столбцы, за исключением случая, когда этот столбец используется как параметр агрегирующей функции. Например, следующий запрос является некорректным:
SELECT staffNo, COUNT(salary)
FROM Staff;
Ошибка состоит в том, что в данном запросе отсутствует конструкция GROUP BY, а обращение к столбцу staffNo в списке выборки SELECT выполняется без применения агрегирующей функции.
Группирование результатов (конструкция GROUP BY)
Приведенные выше примеры сводных данных подобны итоговым строкам, обычно размещаемым в конце отчетов. В итогах все детальные данные отчета сжимаются в одну обобщающую строку. Однако очень часто в отчетах требуется формировать и промежуточные итоги. Для этой цели в операторе SELECT может указываться конструкция GROUP BY. Запрос, в котором присутствует конструкция GROUP BY, называется группирующим запросом, поскольку в нем группируются данные, полученные в результате выполнения операции SELECT, после чего для каждой отдельной группы создается единственная итоговая строка. Столбцы, перечисленные в конструкции GROUP BY, называются группируемыми столбцами. Стандарт ISO требует, чтобы конструкции SELECT и GROUP BY были тесно связаны между собой. При использовании в операторе SELECT конструкции GROUP BY каждый элемент списка в списке выборки SELECT должен иметь единственное значение для всей группы. Более того, конструкция SELECT может включать только следующие типы элементов:
• имена столбцов;
• агрегирующие функции;
• константы;
• выражения, включающие комбинации перечисленных выше элементов.
Все имена столбцов, приведенные в списке выборки SELECT, должны присутствовать и в конструкции GROUP BY, за исключением случаев, когда имя столбца используется только в агрегирующей функции. Противоположное утверждение не всегда справедливо — в конструкции GROUP BY могут присутствовать имена столбцов,отсутствующие в списке выборки SELECT. Если совместно с конструкцией GROUP BY используется конструкция WHERE, то она обрабатывается в первую очередь, а группированию подвергаются только те строки, которые удовлетворяют условию поиска.
Стандартом ISO определено, что при проведении группирования все отсутствующие значения рассматриваются как равные. Если две строки таблицы в одном и том же группируемом столбце содержат значения NULL и идентичные значения во всех остальных непустых группируемых столбцах, они помещаются в одну и ту же группу.
Ограничения на выполнение группирования (конструкция HAVING)
Конструкция HAVING предназначена для использования совместно с конструкцией GROUP BY для задания ограничений, указываемых с целью отбора тех групп, которые будут помещены в результирующую таблицу запроса. Хотя конструкции HAVING и WHERE имеют сходный синтаксис, их назначение различно.
Конструкция WHERE предназначена для отбора отдельных строк, предназначенных для заполнения результирующей таблицы запроса, а конструкция HAVING используется для отбора групп, помещаемых в результирующую таблицу запроса. Стандарт ISO требует, чтобы имена столбцов, применяемые в конструкции HAVING, обязательно присутствовали в списке элементов GROUP BY или применялись в агрегирующих функциях. На практике условия поиска в конструкции
HAVING всегда включают, по меньшей мере, одну агрегирующую функцию; в противном случае эти условия поиска должны быть помещены в конструкцию WHERE и применены для отбора отдельных строк. (Помните, что агрегирующие функции не могут использоваться в конструкции WHERE.)
Конструкция HAVING не является необходимой частью языка SQL —- любой запрос, написанный с использованием конструкции HAVING, может быть представлен в ином виде, без ее применения.
Подзапросы
В этом разделе мы обсудим использование законченных операторов SELECT, внедренных в тело другого оператора SELECT. Внешний (второй) оператор SELECT использует результат выполнения внутреннего (первого) оператора для определения содержания окончательного результата всей операции. Внутренние запросы могут находиться в конструкциях WHERE и HAVING внешнего оператора SELECT —в этом случае они получают название подзапросов, или вложенных запросов. Кроме того, внутренние операторы SELECT могут использоваться в операторах INSERT,UPDATE и DELETE (см. раздел 5.3.10). Существуют три типа подзапросов.
• Скалярный подзапрос возвращает значение, выбираемое из пересечения одного столбца с одной строкой, т.е. единственное значение. В принципе скалярный подзапрос может использоваться везде, где требуется указать единственное значение.
• Строковый подзапрос возвращает значения нескольких столбцов таблицы, но в виде единственной строки. Строковый подзапрос может использоваться везде, где применяется конструктор строковых значений, — обычно ото предикаты.
• Табличный подзапрос возвращает значения одного или нескольких столбцов таблицы, размещенные в более чем одной строке. Табличный подзапрос может использоваться везде, где допускается указывать таблицу, например как операнд предиката IN.
К подзапросам применяются следующие правила и ограничения.
1. В подзапросах не должна использоваться конструкция ORDER BY, хотя она может присутствовать во внешнем операторе SELECT.
2. Список выборки SELECT подзапроса должен состоять из имен отдельных столбцов или составленных из них выражений, за исключением случая,когда в подзапросе используется ключевое слово EXISTS (см. раздел 5.3.8).
3. По умолчанию имена столбцов в подзапросе относятся к таблице, имя которой указано в конструкции FROM подзапроса. Однако разрешается ссылаться и на столбцы таблицы, указанной в конструкции FROM внешнего запроса, для чего используются уточненные имена столбцов (как описано ниже).
4. Если подзапрос является одним из двух операндов, участвующих в операции сравнения, то подзапрос должен указываться в правой части этой операции. Например, приведенный ниже вариант записи запроса из предыдущего примера является некорректным, поскольку подзапрос размещен в левой части операции сравнения со значением столбца salary.
SELECT staffNo, fName, IName, position, salary
FROM Staff
WHERE (SELECT AVG(salary) FROM Staff) < salary;
Ключевые слова ANY и ALL
Ключевые слова ANY и ALL могут использоваться с подзапросами, возвращающими один столбец чисел. Если подзапросу будет предшествовать ключевое слово ALL, условие сравнения считается выполненным только в том случае, если оно выполняется для всех значений в результирующем столбце подзапроса. Если тексту подзапроса предшествует ключевое слово ANY, то условие сравнения будет считаться выполненным, если оно удовлетворяется хотя бы для какого-либо (одного или нескольких) значения в результирующем столбце подзапроса. Если в результате выполнения подзапроса будет получено пустое значение, то для ключевого слова ALL условие сравнения будет считаться выполненным, а для ключевого слова ANY — невыполненным. Согласно стандарту ISO дополнительно можно использовать ключевое слово SOME, являющееся синонимом ключевого слова ANY.
Многотабличные запросы
Все рассмотренные выше примеры имеют одно и то же важное ограничение: помещаемые в результирующую таблицу столбцы всегда выбираются из единственной таблицы. Однако во многих случаях этого оказывается недостаточно. Для того чтобы объединить в результирующей таблице столбцы из нескольких исходных таблиц, необходимо выполнить операцию соединения. В языке SQL операция соединения используется для объединения информации из двух таблиц посредством образования пар связанных строк, выбранных из каждой таблицы.
Помещаемые в объединенную таблицу пары строк составляются по равенству входящих в них значений указанных столбцов.
Выполнение соединений
Соединение является подмножеством более общей комбинации данных двух таблиц, называемой декартовым произведением (см. раздел 4.1.2). Декартово произведение двух таблиц представляет собой другую таблицу, состоящую из всех возможных пар строк, входящих в состав обеих таблиц. Набор столбцов результирующей таблицы представляет собой все столбцы первой таблицы, за которыми следуют все столбцы второй таблицы. Если ввести запрос к двум таблицам без задания конструкции WHERE, результат выполнения запроса в среде SQL будет представлять собой декартово произведение этих таблиц. Кроме того, стандарт ISO предусматривает специальный формат оператора SELECT, позволяющий вычислить декартово произведение двух таблиц:
-."SELECT [DISTINCT. | ALL] {* j columnList]
FROM tableNamel CROSS JOIN СаЫеУлте2
Еще раз рассмотрим пример 5.24, в котором соединение таблиц client и Viewing выполняется с использованием общего столбца clientNo, При работе с таблицами, содержимое которых приведено в табл. 3.6 и 3.8, декартово произведение этих таблиц будет включать 20 строк (4 строки таблицы Client x 5 строк таблицы viewing = 20 строк). Это эквивалентно выдаче используемого в примере 5.24 запроса, но без применения конструкции WHERE.
Процедура генерации таблицы, содержащей результаты соединения двух таблиц с помощью оператора SELECT, состоит в следующем.
1. Формируется декартово произведение таблиц, указанных в конструкции FROM.
2. Если в запросе присутствует конструкция WHERE, применение условий поиска к каждой строке таблицы декартова произведения и сохранение в таблице только тех строк, которые удовлетворяют заданным условиям.
В терминах реляционной алгебры эта операция называется ограничением декартового произведения.
3. Для каждой оставшейся строки определяется значение каждого элемента, указанного в списке выборки SELECT, в результате чего формируется отдельная строка результирующей таблицы.
4. Если в исходном запросе присутствует конструкция SELECT DISTINCT, из результирующей таблицы удаляются все строки-дубликаты. В реляционнойалгебре действия, выполняемые на 3 и 4 этапах, эквивалентны операции проекции по столбцам, заданным в списке выборки SELECT.
5. Если выполняемый запрос содержит конструкцию ORDER BY, осуществляется переупорядочивание строк результирующей таблицы.
Внешние соединения
При выполнении операции соединения данные из двух таблиц комбинируются с образованием пар связанных строк, в которых значения сопоставляемых столбцов являются одинаковыми. Если одно из значений в сопоставляемом столбце одной таблицы не совпадает ни с одним из значений в сопоставляемом столбце другой таблицы, то соответствующая строка удаляется из результирующей таблицы. Именно это правило применялось во всех рассмотренных выше примерах соединения таблиц. Стандартом ISO предусмотрен и другой набор операторов соединений, называемых внешними соединениями (см. раздел 4.1.3). Во внешнем соединении в результирующую таблицу помещаются также строки, не удовлетворяющие условию соединения.
Ключевые слова EXISTS и NOT EXIST
Ключевые слова EXISTS и NOT EXISTS предназначены для использования только совместно с подзапросами. Результат их обработки представляет собой логическое значение TRUE или FALSE. Для ключевого слова EXISTS результат равен TRUE в том и только в том случае, если в возвращаемой подзапросом результирующей таблице присутствует хотя бы одна строка. Если результирующая таблица подзапроса пуста, результатом обработки ключевого слова EXISTS будет значение FALSE. Для ключевого слова NOT EXISTS используются правила обработки, обратные по отношению к ключевому слову EXISTS. Поскольку по ключевым словам EXISTS и NOT EXISTS проверяется лишь наличие строк в результирующей таблице подзапроса, то эта таблица может содержать произвольное количество столбцов.
Как правило, с целью упрощения во всех следующих за обсуждаемыми ключевыми словами подзапросах применяется такая форма записи:
(SELECT * FROM . . . )
Комбинирование результирующих таблиц
(операции UNION, INTERSECT и EXCEPT)
В языке SQL можно использовать обычные операции над множествами —объединение (union), пересечение (intersection) и разность (difference), — позволяющие комбинировать результаты выполнения двух и более запросов в единую результирующую таблицу.
Объединением двух таблиц А и В называется таблица, содержащая все
строки, которые имеются в первой таблице (А), во второй таблице (В) или в обеих этих таблицах одновременно,
• Пересечением, двух таблиц называется таблица, содержащая все строки,присутствующие в обеих исходных таблицах одновременно.
• Разностью двух таблиц А и В называется таблица, содержащая все строки, которые присутствуют в таблице А, но отсутствуют в таблице В.
Все эти операции над множествами графически представлены на рис. 5.2. На таблицы, которые могут комбинироваться с помощью операций над множествами, накладываются определенные ограничения. Самое важное из них состоит в том, что таблицы должны быть совместимы, по соединению — т.е. они должны иметь одну и ту же структуру. Это означает, что таблицы должны иметь одинаковое количество столбцов, причем в соответствующих столбцах должны размещаться данные одногои того же типа и длины. Обязанность убедиться в том, что значения данных соответствующих столбцов принадлежат одному и тому же домену, возлагается на пользователя. Например, мало смысла в том, чтобы объединять столбец с данными о возрасте работников с информацией о количестве комнат в сдаваемых в аренду объектах, хотя оба столбца будут иметь один и тот же тип данных — SMALLINT. При указании конструкции CORRES POND ING BY операция над множествами выполняется для указанных столбцов. Если задано только ключевое слово CORRESPONDING, а конструкция 3Y отсутствует, операция над множествами выполняется для столбцов, которые являются общими для обеих таблиц. Если указано ключевое слово ALL, результирующая таблица может содержать повторяющиеся строки.
Одни диалекты языка SQL не поддерживают операций INTERSECT и EXCEPT, a в других вместо ключевого слова EXCEPT используется ключевое слово MINUS.
Изменение содержимого базы данных SQL является полнофункциональным языком манипулирования данными, который может использоваться не только для выборки данных из базы, но и для модификации ее содержимого. Операторы модификации информации в базе данных не столь сложны, как оператор SELECT. В этом разделе рассматриваются три оператора языка SQL, предназначенных для модификации содержимого базы данных.
• INSERT — предназначен для добавления данных в таблицу,
• UPDATE — предназначен ,иля модификации уже помещенных в таблицу данных.
• DELETE — позволяет удалять из таблицы строки данных.
Добавление новых данных в таблицу (оператор INSERT)
Существуют две формы оператора INSERT. Первая предназначена для вставки единственной строки в указанную таблицу. Эта форма оператора INSERT имеет следующий формат:
# INSERT . INTO TableName Г
^VALUES
Здесь параметр TableName (Имя таблицы) может представлять либо имя таблицы базы данных, либо имя обновляемого представления (раздел 6.4). Параметр colunmList (Список столбцов) представляет собой список, состоящий из имен одного или более столбцов, разделенных запятыми. Параметр coIumnLisC является необязательным. Если он опущен, то предполагается использование списка из имен всех столбцов таблицы, указанных в том порядке, в котором они были описаны в операторе CREATE TABLE. Если в операторе INSERT указывается конкретный список имен столбцов, то любые опущенные в нем столбцы должны быть объявлены при создании таблицы как допускающие значение NULL — за исключением случаев, когда при описании столбца использовался параметр DEFAULT (раздел 6.3.2). Параметр dataValueList (Список значений данных) должен следующим образом соответствовать параметру columnList:
т количество элементов в обоих списках должно быть одинаковым;
• должно существовать прямое соответствие между позицией одного и того же элемента в обоих списках, поэтому первый элемент списка da ta Val uebist считается относящимся к первому элементу списка columnList, второй элемент списка dataValuel/ist — ко второму элементу списка columnList и т.д.;
• типы данных элементов списка dataValueList должны быть совместимы с типом данных соответствующих столбцов таблицы.
Модификация данных в базе (оператор UPDATE)
Оператор UPDATE позволяет изменять содержимое уже существующих строк указанной таблицы. Этот оператор имеет следующий формат:
^UPDATE. ТаЫеПате
SET calumnNamel = dataValuel
[WHERE searchCondition]
columnNameS '*= dataValue2…)
Здесь параметр TableN&me представляет либо имя таблицы базы данных, либо имя обновляемого представления (см. раздел 6.4). В конструкции SET указываются имена одного или более столбцов, данные в которых необходимо изменить. Конструкция WHERE является необязательной. Если она опущена, значения указанных столбцов будут изменены во всех строках таблицы. Если конструкция WHERE присутствует, то обновлены будут только те строки, которые удовлетворяют условию поиска, заданному в параметре searchCondition. Параметры dataValuel, dataValue2t... представляют новые значения соответствующих столбцов и должны быть совместимы с ними по типу данных.
Удаление данных из базы (оператор DELETE)
Оператор DELETE позволяет удалять строки данных из указанной таблицы.
Этот оператор имеет следующий формат:
'''DELETE FROM TableName
:[WHERE searchConditionJ
Как и в случае операторов INSERT и UPDATE, параметр TableName может представлять собой либо имя таблицы базы данных, либо имя обновляемого представления (см. раздел 6.4). Параметр searchCondition является необязательным — если он опущен, из таблицы будут удалены все существующие в ней строки. Однако сама по себе таблица удалена не будет. Если необходимо удалить не только содержимое таблицы, но и ее определение, следует использовать оператор DROP TABLE (см. раздел 6.3.3). Если конструкция WHSRE присутствует, из таблицы будут удалены только те строки, которые удовлетворяют условию отбора, заданному параметром searchCondition,