
- •1.2. Объединение наборов записей (union)
- •1.3. Пересечение наборов записей (intersect)
- •Intersect corresponding( id_компонента, Тип_компонента)
- •1.4. Вычитание наборов записей (except)
- •2. Операции соединения
- •2.1. Естественное соединение (natural join)
- •2.2. Условное соединение (join... On)
- •2.3. Соединение по именам столбцов (join... Using)
- •2.4. Внешние соединения
- •Задание для самостоятельной работы:
Материал для подготовки к практической работе по теме:
«Теоретико-множественные операции и операции соединения с SQL»
Задания:
Внимательно изучите предложенный теоретический материал.
Письменно заполните таблицу, которая приведена в конце документа.
Реализуйте на практике все специально выделенные практические примеры (отмечены символом ). Для этого откройте Учебную базу данных.
Теоретический материал для изучения:
Теоретико-множественные операции
Над наборами записей, содержащихся в таблицах базы данных и/или возвращаемых запросами, можно совершать теоретико-множественные операции, такие как декартово произведение, объединение, пересечение и вычитание.
1.1. Декартово произведение наборов записей
Запрос SELECT списокСтолбцов FROM Т1, Т2, ... Тn;
возвращает набор записей, полученный в результате декартового произведения наборов записей из таблиц T1, T2,..., Тn. Таблицы, указанные в операторе FROM, могут быть как таблицами базы данных, так и виртуальными таблицами, возвращаемыми какими-нибудь запросами.
Иногда требуется получить декартово произведение таблицы самой на себя. В этом случае необходимо применить различные псевдонимы для этой таблицы, например:
SELECT списокСтолбцов FROM Mytab T1, Mytab T2;
Обратите внимание, что попытка выполнить запрос:
SELECT списокСтолбцов FROM Mytab, Mytab;
приведет к ошибке.
В списке столбцов следует использовать полные имена столбцов, используя псевдонимы таблиц, или символ (*), если требуется получить все столбцы.
Для декартова произведения в SQL также допустим синтаксис с ключевыми словами CROSS JOIN (перекрестное соединение):
SELECT списокСтолбцов FROM Mytab T1 CROSS JOIN Mytab T2;
Примечание:
Рассмотренные выражения работают в полнофункциональных базах данных. В Microsoft Access для получения декартового произведения возможно использование выражения (SELECT списокСтолбцов FROM T1, T2, ... Tn), только если все таблицы в списке имеют различные имена. Если требуется декартово произведение таблицы самой на себя, то в выражении (select списокСтолбцов FROM Mytab T1, Mytab T2) Access автоматически добавит ключевое слово AS перед каждым псевдонимом. Попытка использования ключевых слов CROSS JOIN в Access приведет к ошибке.
Запросы на декартово произведение сами по себе очень редко используются. Они приобретают некоторый смысл, если применяются с оператором WHERE.
Пример:
Допустим, что имеется таблица Рейсы (НАЧАЛЬНЫЙ_ПУНКТ, КОНЕЧНЫЙ_ПУНКТ), содержащая сведения о том, из каких пунктов и в какие можно попасть с помощью того или иного авиарейса.
На рис. показан граф достижимости пунктов некоторым авиарейсом и соответствующая ему таблица Рейсы. Каждой стрелке на графе и каждой записи таблицы соответствует некоторый рейс. Не трудно заметить, что из некоторых пунктов в другие можно попасть только с пересадкой на другой рейс, т. е. через транзитный пункт. Следующий запрос возвращает таблицу (рис. ниже), содержащую сведения о достижимости пунктов в точности через один транзитный пункт:
SELECT Т1.НАЧАЛЬНЫЙ_ПУНКТ, Т2.КОНЕЧНЫЙ_ПУНКТ
FROM Рейсы Т1, Рейсы Т2
WHERE T1.КОНЕЧНЫЙ_ПУНКТ = Т2.НАЧАЛЬНЫЙ_ПУНКТ;
Р
ассмотрим
данный запрос более подробно. Сначала
он выполняет декартово произведение
таблицы Рейсы на эту же таблицу. В
результате получается таблица с четырьмя
столбцами:
Т1.НАЧАЛЬНЫЙ_ПУНКТ,
Т1.КОНЕЧНЫЙ__ПУНКТ,
Т 2 .НАЧАЛЬНЫЙ_ПУНКТ
и Т2.КОНЕЧНЫЙ_ПУНКТ.
Затем из полученной таблицы выбираются такие записи, в которых Т1.КОНЕЧНЫЙ_ПУНКТ = Т2.НАЧАЛЬШЙ_ПУНКТ. Это и есть пары пунктов, между которыми в графе достижимости находится один промежуточный пункт. Наконец, из четырех столбцов выделяются только два: Т1.НАЧАЛЬНЫЙ_ПУНКТ и Т2.КОНЕЧНЫЙ_ПУНКТ.
1.2. Объединение наборов записей (union)
Нередко требуется объединить записи двух или более таблиц с похожими структурами в одну таблицу. Иначе говоря, к набору записей, возвращаемому одним запросом, требуется добавить записи, возвращаемые другим запросом. Для этого служит оператор union (объединение):
Запрос1 UNION Запрос2;
При этом в результатной таблице остаются только отличающиеся записи. Чтобы сохранить в ней все записи, после оператора UNION следует написать ключевое слово ALL.
Например, таблицы клиенты и контакты имеют однотипные столбцы Имя и Адрес. Тогда, чтобы пополнить список данных о клиентах сведениями из таблицы контакты, достаточно выполнить следующий запрос:
SELECT Имя, Адрес FROM Клиенты
UNION
SELECT Имя, Адрес FROM Контакты;
Возможно, что в обеих объединяемых таблицах, Клиенты и Контакты, имеются записи с одинаковыми парами значений в столбцах имя и Адрес. Однако в результатной таблице данного запроса повторений не будет, как если бы вы использовали оператор UNION DISTINCT.
Оператор UNION можно применять только таблицам, удовлетворяющим следующим условиям совместимости:
- количества столбцов объединяемых таблиц должны быть равны;
- данные в соответствующих столбцах объединяемых таблиц должны иметь совместимые типы. Например, символьные (строковые) типы char и varchar совместимы, а числовой и строковый типы не совместимы.
Обратите внимание, что имена соответствующих столбцов и их размеры могут быть различными. Важно, чтобы количества столбцов были равны, а их типы были совместимы. Чтобы объединить наборы записей с несовместимыми по типу данных столбцами, следует применить функцию преобразования типа данных cast (). Например, следующий запрос возвращает список имен клиентов, к которому добавлен список сумм заказов (не будем обсуждать практическую пользу или смысл такого списка):
SELECT Имя FROM Клиенты
UNION
SELECT СAST(Сумма__заказа AS CHAR (10)) FROM Клиенты;
Когда требуется объединить записи двух таблиц, имеющих одноименные столбцы с совместимыми типами, можно использовать оператор UNION CORRESPONDING (объединение соответствующих):
SELECT * FROM Таблица1
UNION CORRESPONDING (списокСтолбцов)
SELECT * FROM Таблица2;
После ключевого слова CORRESPONDING можно указать столбцы, имеющиеся одновременно в обеих таблицах. Если этот список столбцов не указан, то предполагается список всех имен. При этом возможны недоразумения.
Пример:
Пусть требуется получить сведения о том, в какие пункты можно попасть, сделав не более одной пересадки (т. е. без пересадок или с одной пересадкой). Для этого достаточно объединить записи исходной таблицы Рейсы с результатом запроса о достижимости через один промежуточный пункт:
SELECT НАЧАЛЬНЫЙ_ПУНКТ, КОНЕЧНЫЙ_ПУНКТ FROM Рейсы
UNION
SELECT Т1.НАЧАЛЬНЫЙ_ПУНКТ, Т2.КОНЕЧНЫЙ_ПУНКТ FROM Рейсы Т1, Рейсы Т2
WHERE Т1.КОНЕЧНЫЙ_ПУНКТ=Т2.НАЧАЛЬНЫЙ_ПУНКТ;
Р
езультат
данного запроса показан на рис. слева.
Аналогичным образом можно сформулировать запрос о достижимости пунктов, в которые можно попасть посредством не более двух, трех и т. д. пересадок.
Рассмотренный запрос возвращает сведения о достижимости пунктов из всех возможных начальных пунктов. А если нам нужны сведения о достижимости только из одного пункта, например, А?
В этом случае достаточно добавить еще одно условие в оператор WHERE:
SELECT НАЧАЛЬНЫЙ_ПУНКТ, КОНЕЧНЫЙ_ПУНКТ FROM Рейсы
UNION
SELECT Т1. НАЧАЛЬНЫЙ, ПУНКТ, Т2.КОНЕЧНЫЙ_ПУНКТ
FROM Рейсы Т1, Рейсы Т2
WHERE T1.КОНЕЧНЫЙ_ПУНКТ = Т2.НАЧАЛЬНЫЙ_ПУНКТ
AND T1.НАЧАЛЬНЫЙ_ПУНКТ = 'А';