Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Белобжеский_Лекции_по_ББД.doc
Скачиваний:
3
Добавлен:
01.07.2025
Размер:
5.5 Mб
Скачать

Внешнее соединение

Стандарт ANSI SQL не поддерживает операцию внешнего соединения. Однако эта операция поддерживается многими СУБД. Здесь мы продемонстрируем ис­пользование одной из них.

Предположим, нам нужен список студентов и названия предметов, на которые они записаны. Допустим, кроме того, что мы хотим получить сведения обо всех студентах, включая даже тех, кто не записан ни на один из предметов. В Microsoft Access этот результат можно получить с помощью следующего выражения:

SELECT Имя, НазваниеПредмета

FROM СТУДЕНТ LEFT JOIN ЗАПИСЬ

ON ЛичныйНомер = НомерСтудента;

Результатом будет:

ДЖОНС

BD445

ПАРКС

ВА200

БЕЙКЕР

BD445

БЕЙКЕР

CS250

ГЛАСС

Null

БЕЙКЕР

CS150

РАССЕЛ

Null

РАЙ

ВА200

РАЙ

BF410

РАЙ

CS250

ДЖОНС

ВА200

Обратите внимание на различия между Access SQL и записью, принятой в стан­дарте ANSI. Условия соединения задаются с помощью ключевого слова ON. Кроме того, все выражения SQL заканчиваются точкой с запятой.

Операторы exists и not exists

(Смотри также далее !!!!)

EXISTS и NOT EXISTS («существует» и «не существует») — логические операторы, принимающие значение «истина» или «ложь», в зависимости от наличия или от­сутствия строк, удовлетворяющих заданным условиям. Пусть, например, мы хо­тим узнать номера студентов, записанных более чем на один предмет:

SELECT DISTINCT НомерСтудента

FROM ЗАПИСЬ А

WHERE EXISTS

(SELECT*

FROM ЗАПИСЬ В

WHERE А.НомерСтудента = В.НомерСтудента

AND А.НазваниеПредмета NOT = В.НазваниеПредмета)

В этом примере как основной, так и вложенный запросы относятся к таблице ЗАПИСЬ. Во избежание неоднозначности этим двум вариантам использования таблицы ЗАПИСЬ присвоены различные имена. В первом операторе FROM таблице ЗАПИСЬ присвоено временное произвольное имя А, а во втором операторе FROM — другое временное произвольное имя В.

Выражение во вложенном запросе означает следующее: следует найти две строки в таблице ЗАПИСЬ, имеющие один и тот же номер студента, но различные названия предметов. (Это означает, что студент записан более чем на один пред­мет.) Если такие две строки существуют, то оператор EXISTS будет иметь логическое значение «истина»; в этом случае номер данного студента будет присутство­вать в ответе. В противном случае оператор EXISTS будет иметь логическое значение «ложь», и номер данного студента в результате фигурировать не будет.

Можно рассматривать этот запрос и по-другому: представим себе две отдель­ные и идентичные копии таблицы ЗАПИСЬ. Назовем одну из копий А, а другую В. Будем сравнивать каждую строку А с каждой строкой В. Сначала рассмотрим первую строку А и первую строку В. Поскольку эти две строки идентичны, то и номер студента, и название предмета в них совпадают, поэтому атрибут Номер-Студента из данной строки не попадет в ответ.

Теперь рассмотрим первую строку А и вторую строку В. Если номер студента один и тот же, а названия предметов различаются, данный номер студента будет отображен в результатах. В сущности, мы сравниваем первую строку таблицы ЗАПИСЬ со второй строкой этой же таблицы. В данных, представленных на рис. 9.2, ни номер студента, ни название предмета не совпадают.

Далее мы продолжаем сравнивать первую строку А с каждой строкой В, Если выполняются заданные нами условия, мы выводим номер студента. Когда будут пройдены все строки таблицы В, мы перейдем ко второй строке таблицы А и будем сравнивать ее с каждой строкой таблицы В (на самом деле, когда мы рассматри­ваем п-ю строку таблицы А, то в таблице В необходимо рассмотреть только стро­ки, номера которых больше п).

Результатом этого запроса будет:

Чтобы продемонстрировать использование ключевого слова NOT EXISTS , пред­положим, что мы хотим узнать имена студентов, которые записаны на все пред­меты (Операция ДЕЛЕНИЯ рел. Алгебры). По-другому это можно выразить так: нам нужны имена таких студентов, для которых не существует предметов, на которые они не были бы записаны. Это делается с помощью следующего запроса:

SELECT СТУДЕНТ.Имя

FROM СТУДЕНТ

WHERE NOT EXISTS

(SELECT*

FROM ЗАНЯТИЯ

WHERE NOT EXISTS

(SELECT*

FROM ЗАПИСЬ

WHERE ЗАНЯТИЯ.НазваниеПредмета = ЗАПИСЬ.НазваниеПредмета

AND ЗАПИСЬ.НомерСтудента = СТУДЕНТ.ЛичныйНомер))

Этот запрос состоит из трех частей. В нижней части ведется поиск предметов, на которые записан студент. Средняя часть определяет, есть ли такие предметы, на которые студент не записан. Если нет, то студент записан на все предметы, и его имя отображается в результатах.

Этот запрос может оказаться сложным для понимания. Если у вас есть пробле­мы с этим, используйте данные, представленные на рис. 9.2, и следуйте инструк­циям. Для этих данных ответ состоит в том, что нет ни одного студента, который был бы записан на все предметы. Вы можете попытаться изменить данные таким образом, чтобы какой-либо студент был записан на все предметы. Еще один спо­соб уяснить себе суть этого запроса — попробовать представить его в другом виде, без применения ключевого слова NOT EXISTS. Проблемы, с которыми вы при этом столкнетесь, помогут вам понять, почему оператор NOT EXISTS необходим.