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

db / Лекции / 6 семестр / Языки запросов_раздел_1_4

.pdf
Скачиваний:
42
Добавлен:
23.03.2015
Размер:
831.91 Кб
Скачать

1.4.5 Соединение таблиц по неравенству

До сих пор мы соединяли таблицы по равенству двух столбцов, однако

SQL позволяет для соединения таблиц использовать любое допустимое для сравнения столбцов условие. Рассмотрим ряд примеров.

Запрос. Вывести названия факультетов, фонд финансирования которых меньше фонда финансирования какой-нибудь из кафедр.

SELECT DISTINCT f.Name

FROM FACULTY f, DEPARTMENT d

WHERE f.Fund < d.Fund;

Запрос. Вывести названия факультетов, фонд финансирования которых меньше фонда финансирования какой-нибудь из кафедр.

SELECT DISTINCT f.Name

FROM FACULTY f, DEPARTMENT d

WHERE f.Fund < d.Fund;

Как вы можете убедиться по приведенным примерам, соединения таблиц по условиям, отличающимся от равенства, во многом искусственны. Поэтому в подавляющем большинстве случаев таблицы соединяются по равенству, а

условия по неравенству используются для дополнительного отбора строк.

1.4.6 Самосоединение таблицы

Как правило, взаимосвязи существуют и в пределах одной таблицы. В од-

них случаях эти связи являются явными, например, когда внешний ключ ссыла-

ется на первичный ключ той же самой таблицы (как в случае столбца CHIEF

таблицы TEACHER). В других случаях эта связь присутствует неявно, напри-

мер, кафедры могут быть связаны между собой на основании того свойства, что располагаются в одном корпусе.

Для ответа на такие запросы следует осуществлять соединение таблицы со своей копией. Такое соединение иногда называют самосоединением таблицы.

Несмотря на кажущуюся искусственность идеи самосоединения таблиц, суще-

ствует множество запросов, которые требуют именно такого соединения. На приводимых далее примерах вы убедитесь в этом.

Чтобы произвести соединение таблицы со своей копией, необходимо ука-

зать во фразе FROM имя одной и той же таблицы два или большее количество

раз, а во фразе WHERE — условие их самосоединения. Однако в этом случае возникает следующая проблема — как ссылаться на столбцы различных копий таблицы. До сих пор проблема ссылки на столбцы с одинаковыми именами из разных таблиц разрешалась уточнением имени столбца именем таблицы. В

нашем же случае соединяемые таблицы имеют одинаковые имена.

Для разрешения этой проблемы без псевдонимов таблиц уже не обойтись.

В нашем случае различным вхождениям одной и той же таблицы приписыва-

ются различные псевдонимы и именно по этим псевдонимам производится об-

ращение к столбцам.

Приведем примеры использования самосоединения.

Запрос. Вывести номера групп, рейтинг которых превышает рейтинг группы 504 пятого курса.

SELECT searched.Num

FROM SGROUP given, SGROUP searched

WHERE given.Num = 504 AND given.Year = 5 AND

searched.Rating > given.Rating;

Запрос. Вывести фамилии преподавателей, зарплата которых больше, чем

у преподавателя Сидорова.

SELECT needed.Name

FROM TEACHER needed, TEACHER given

WHERE needed.Salary + needed.Rise > given.Salary + given.Rise AND UPPER(given.Name) = 'СИДОРОВ';

Запрос. Вывести пары преподавателей, которые читают одинаковые дис-

циплины в один и тот же день с указанием дисциплины и дня.

SELECT DISTINCT tl.Name AS ФИ0_1, t2.Name AS ФИ0_2, s.Name AS

Предмет, l1.Day AS День

FROM LECTURE l1, LECTURE l2, TEACHER tl, TEACHER t2, SUBJECT s WHERE U.SbjFK = l2.SbjFK AND

LOWER(U.Day) = LOWER(l2.Day) AND

U.TchFK = tl.TchPK AND l2.TchFK = t2.TchPK AND

U.SbjFK = s.SbjPK AND

tl.Name < t2.Name;

Основная конструкция запроса – соединение таблицы LECTURE со своей копией по равенству номера предмета (l1.SbjFK=l2.SbjFK) и ограничение

результата по равенству дней в обеих таблицах

(LOWER(l1.Day) = L0WER(l2.Day)). В пятой строке фразы WHERE мы делаем запрос (и его результирующую таблицу) асимметричным.

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

словной или любую другую. SQL с помощью самосоединения таблицы позво-

ляет выражать некоторые виды запросов к иерархической структуре. Приведем пример.

Запрос. Вывести фамилии всех преподавателей, непосредственно подчи-

ненных Сидорову.

SELECT sub.Name AS "Подчиненные Сидорова"

FROM TEACHER boss, TEACHER sub

WHERE UPPER(boss.Name) = 'СИДОРОВ' AND boss.TchPK = sub.Chief;

Для иерархической структуры можно формулировать множество видов за-

просов, например:

найти всех подчиненных конкретного лица;

найти всех подчиненных самого нижнего уровня иерархии;

для конкретного лица найти всех его руководителей, вплоть до руково-

дителя самого верхнего уровня.

В одном из следующих мы вернемся к рассмотрению возможностей SQL

по работе с иерархическими структурами данных и познакомимся с рекурсив-

ными запросами.

1.4.7 Внешнее соединение таблиц

Предположим, необходимо вывести список факультетов и их кафедр. Это достигается соединением таблиц FACULTY и DEPARTMENT по равенству значений первичного и внешнего ключей и выбором столбцов с названиями факультетов и кафедр. Но в таком случае, если на факультете кафедр нет, он не будет включен в результат.

Для того чтобы в списке присутствовали все факультеты, даже без кафедр,

необходимо использовать внешнее соединение, которое расширяет возможности обычного соединения. Внешнее соединение возвращает строки, которые удовле-

творяют условию соединения, а также те строки одной из таблиц, для которых в другой не нашлось удовлетворяющих условию соединения строк. В Oracle син-

таксис внешнего соединения имеет следующие два варианта:

таблица.столбец оператор_сравнения таблица.столбец (+)

таблица.столбец (+) оператор_сравнения таблица.столбец

Когда в результат должны быть включены все строки таблицы, указанной в левой части, следует использовать первый вариант. Такое соединение называ-

ется левым внешним соединением. Если необходимо, чтобы в результате при-

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

Запрос. Вывести фамилии всех преподавателей с указанием их кафедры,

если она есть.

SELECT d.Name AS "Название_кафедры", t.Name AS "Фамилия преподавателя"

FROM DEPARTMENT d, TEACHER t

WHERE d.DepPK (+) = t.DepFK;

Название кафедры

Фамилия преподавателя

 

 

программирование

Сидоров

программирование

Рамишевский

программирование

Хоренко

программирование

Вибровский

программирование

Воропаев

программирование

Кузинцев

программирование

Завратинский

программирование

Козлутин

программирование

Лекарь

программирование

Мартынов

программирование

Резван

программирование

Недеведеев

NULL

Ахромеев

NULL

Наумов

NULL

Дараганов

Обратите внимание, что в результирующей таблице значения отсутствую-

щего столбца принимают значение NULL.

1.4.8 Соединение с использованием фразы FROM

Все рассмотренные выше типы и способы соединения таблиц можно осу-

ществлять и с помощью фразы FROM. В ней, в соответствии со стандартом

SQL, можно не только перечислить имена таблиц, участвующих в запросе, но и указать их соединение, для чего могут использоваться три различные кон-

струкции.

Уточненное соединение предполагает явное задание условия соединения.

Для этого можно использовать два варианта - фразу USING, с помощью кото-

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

таблица [INNER | {FULL | LEFT | RIGHT} [OUTER]] JOIN таблица {ON условие | USING

(список_столбцов)}

Естественное соединение выполняется по равенству значений всех пар од-

ноименных столбцов таблиц и не требует задания каких-либо условий. Оно имеют следующий синтаксис:

таблица NATURAL [INNER | {FULL | LEFT | RIGHT} [OUTER]] JOIN таблица

Перекрестное соединение эквивалентно декартовому произведению таб-

лиц. Его синтаксис самый простой:

таблица CROSS JOIN таблица

1.4.9 Итоги лекции

Усвоив материал этого урока, студенты научились:

соединять таблицы по равенству и по произвольному условию;

соединять три и более таблицы;

производить самосоединение таблицы;

строить асимметричные запросы;

строить запросы к иерархическим данным;

выполнять внешние соединения таблиц.