Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Информатика_лекции_Саладаев.doc
Скачиваний:
60
Добавлен:
03.05.2015
Размер:
15.75 Mб
Скачать

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

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

При операции соединения (join) таблицы перечисляются в предложении запросаFROMчерез запятую. Предикат запроса может ссылаться на любой столбец из соединяемых таблиц (обычноWHERE). Имена таблиц предшествуют через точку именам полей.

SELECT Customers.cname, Sales people.sname, Sales people.city

FROM Sales people, Customers

WHERE Sales people. city = Customers.city;

Это типичный пример, когда префиксы действительно необходимы (и в одной и в другой таблице поле- city). В дальнейшем префиксы используем по необходимости.

В запросе для каждого продавца из Salespeopleпроводится проверка предиката.

Операция соединения таблиц посредством ссылочной целостности

Допустим, что между таблицами существует связь по полю snum- номер продавца (за каждым покупателем закреплен продавец).

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

SELECT Customers cname, Salespeople.sname

FROM Customers, Salespeople

WHERE Salespeople.snum = Customers.snum;

Поля snumне представлены в выходных данных, поскольку они не существенны как результаты. Подобным образом могут быть построены объединения нескольких таблиц (>2).

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

Здесь возникает проблема с именами. У копии должны быть другие имена. Проблема решается определением временных имен- алиасовв предложенииFROM. Рассмотрим пример поиска пар продавцов, имеющих одинаковый рейтинг:

SELECT first.sname, second.sname, first.rating

FROM Salespeople first, Salespeople second

WHERE first.rating = second.rating;

SQLне делает копии реально, но внешне это выглядит так, чтоSalespeopleраспадается на две копии с именамиfirstиsecond.

После выполнения запроса алиасы утрачивают силу.

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

Есть простой способ исключить трехкратныеповторения- сделать предикатасимметричным.

SELECT first.sname, first.rating

FROM Salespeople first, Salespeople second

WHERE first.rating = second.rating;

AND first.sname < second.sname;

Это уже полезный прием для работы.

Алиасы используют не только для копий запросов, но и просто при замене длинных имен короткими.

Вложение запросов (подзапросы).

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

Допустим, нам нужны все заказы продавца с именем Hoffman. Его номера мы не знаем.

SELECT *

FROM Orders

WHERE Snum = (SELECT Snum FROM Sales people

WHERE sname = ‘Hoffman’);

Если бы мы знали номер (допустим 1004), то мы бы прямо написали:

WHERE snum = 1004;

но 1004- это результат подзапроса.

Здесь есть тонкость. Вы должны быть уверены, что это значение единственное (результат подзапроса), иначе будет ошибка.

Если получится NULL, то ошибки не будет. Предикат сработает поUNKnownтак же как поFALSEи не выдаст ни одной строки в результате.

Для гарантии единственности результата в подзапросе после слова SELECTнужно поставитьDISTINCT.

Еще одно ограничение стандарта ANSI- нельзя подзапрос поставить слева (перед запросом).