Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
db / Лекции / 6 семестр / Языки запросов.docx
Скачиваний:
100
Добавлен:
23.03.2015
Размер:
280.32 Кб
Скачать
      1. Соединение таблиц по неравенству

До сих пор мы соединяли таблицы по равенству двух столбцов, однако 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. Самосоединение таблицы

Как правило, взаимосвязи существуют и в пределах одной таблицы. В одних случаях эти связи являются явными, например, когда внешний ключ ссылается на первичный ключ той же самой таблицы (как в случае столбца 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по работе с иерархическими структурами данных и познакомимся с рекурсивными запросами.