Предположим, нам надо получить ответ на вопрос: сколько заказов сделал покупатель с фамилией Семенов, причем в результате мы хотим получить таблицу, которая содержит только 4-ре следующих столбца: номер заказа, дата заказа, фамилия покупателя и фамилия продавца. Понятно, сто из одной таблицы Orders (Заказы) мы всю необходимую информацию по данному запросу не получим, т.к. таблица orders не содержит полей sname и cname. Поэтому для построения этого запроса необходимо привлечь таблицы Customers и Salespeople.
Для построения запросов над несколькими таблицами в Access удобно пользоваться режимом Конструктор (Запросы®Конструктор), который открывает окно построения запроса QBE, состоящее из двух частей: зона таблиц (сверху) и зона таблицы запроса (снизу) (более подробно о QBE см. Занятие 1).
Рис.3.1. Пример построения запроса с тремя таблицами.
В верхнюю зону поместим три таблицы Customers, Orders и Salespeople, в нижнюю часть (зона запроса) выберем столбцы: onum и odate из таблицы orders, cname из таблицы Customers и sname из таблицы Salespeople, как показано на рис. 31. выше.
В столбце с именем покупателя (cname.customers) запишем условие отбора записей (“Семенов”). Выполнение запроса даст следующий результат, который показан на рис. 32, т.е. будут отобраны только строки с заказами, которые обслужили покупателя с фамилией «Семенов».
Рис.32. Результат запроса к БД «Авто.mdb»
Посмотрим, как выглядит это запрос в режиме SQL, для чего войдем в редактор языка SQL через соответствующую пиктограмму или выполнив команду Вид®Запрос на SQL. Открывается окно редактора SQL и теперь мы можем рассмотреть текст запроса на языке SQL:
FROM Salespeople INNER JOIN (customers INNER JOIN orders ON customers.cnum = orders.cnum) ON Salespeople.snum = orders.snum
WHERE (((customers.cname)="Семенов"));
Отметим, что имена столбцов в строке с ключевым словом SELECT записаны в полной синтаксической структуре: <имя таблицы>.<имя столбца>. Это необходимо, чтобы каждый столбец был четко и однозначно приписан к соответствующей таблице.
В строке с ключевым словом FROM используются все три таблицы Oreds, Salespeple и Customers, которые объединены с помощью оператора INNER JOIN и с указанием соответствующих условий связи между ними ( в нашем случае customers.cnum = orders.cnum и Salespeople.snum = orders.snum).
Разобраться в структуре такого SQL сразу достаточно трудно, поэтому попытаемся создать аналогичный запрос вручную с помощью редактора SQL-запросов, путем построения сначала более простого запроса на объединение двух таблиц, а затем добавим в него необходимые ограничения с помощью условий.
Запрос сформулируем следующим образом: отобрать все заказы для продавцов, которые живут в городе «Тула» (в Туле живет один продавец) и показать только три столбца (код заказа, дата заказа и фамилию продавца). Очевидно, что в построении запроса должны участвовать две таблицы: Orders и Salespeople.
Сначала составим запрос без условия на отбор строк, используя строки с ключевыми словами SELECT и FROM:
Результатом запроса будет объединение строк таблиц Orders и Salespeople по полям orders.onum и salespeople.sname и мы получим таблицу из 30 записей как показано на рис. 33. ниже, которая отражает всевозможные комбинации указанных столбцов (см. Введение).
Часть строк этого результата являются «лишними» (т.е. не реальными) и не отвечают нашему запросу. Не реальные строки не содержатся в таблице Orders и их надо отсечь. Поэтому чтобы отобрать только «реальные» строки необходимо добавить условие, отражающее межсущностную связь (т.е. связь межу таблицами Salespeople и Orders): Salespeople.snum = Orders.snum, которое требует отбирать только те строки, в которых номер продавца в таблицах совпадает. SQL-запрос с дополнительным условием будет выглядеть так:
Рис. 33. Результат объединения двух таблиц Orders и Salespeople (операция «соединение»)
Результат запроса с учетом межсущностной связи между объединяемыми таблицами показан на рис. 34 ниже.
Теперь получим таблицу с «реальными» строками, которые отражают все строки в таблице Orders и фамилии продавцов.
Рис. 34. Запрос над двумя таблицами с дополнительным условием (Salespeople.snum = orders.snum)
Теперь в текст SQL-запроса добавим еще одно условие отбора строк: живущие в городе «Тула» (или Salespeople.saddress ='Тула') и соединим его при помощи логического оператора AND с условием в строке с ключевым словом WHERE. Полный запрос, отвечающий на поставленный вопрос показан ниже:
WHERE (Salespeople.snum = orders.snum) AND (Salespeople.saddress ='Тула');
В результате получим искомую таблицу с одной строкой, отвечающую на поставленный вопрос (см. рис.35).
Рис.35. Запрос над двумя таблицами с дополнительным условием Salespeople.saddress ='Тула'
Аналогичный результат можно получить, используя оператор INNER JOIN для объединения таблиц с включением условия объединения в строку с ключевым словом FROM. В этом случае запрос на SQL будет выглядеть следующим образом:
FROM Salespeople INNER JOIN Orders ON Salespeople.snum = Orders.snum
WHERE Salespeople.saddress ='Тула';
Следует отметить, что поле snum в таблице Salespeople является первичным ключем, а поле snum в таблице orders – внешним ключом, который используется для связи и организации проверки целостности. Более подробно о целостности в реляционных базах данных смотри в работе []. Таким образом, ключевое слово INNER JOIN с условием на первичных и внешних ключах позволяет упростить структуру запроса над несколькими таблицами, оставляя в строке с ключевым словом WHERE только условия над обычными полями.