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

Access 2007

.pdf
Скачиваний:
115
Добавлен:
11.05.2015
Размер:
23.5 Mб
Скачать

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

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

разд. "Определение отношения" главы 5, или созданием подстановки, как описано в разд. "Поиск в связанных таблицах" главы 5), программа Access использует эту связь для автоматического выполнения операции объединения. Вы увидите на схеме линию, соединяющую соответствующие поля, как показано на рис. 6.17.

Рис. 6.17. Access автоматически соединяет поле CustomerlD в таблице Orders с полем ID в таблице Customers, основываясь на связи, определенной в БД

Если связь между двумя связанными таблицами еще не определена, возможно, это следует сделать до того, как создавать запрос (см. подробные инструкции в главе 5). Но если вы по каким-то непонятным причинам решили не создавать связь (может быть, проект БД был введен в эксплуатацию другим, менее сообразительным специалистом Access), вы можете задать объединение вручную в окне запроса. Для этого просто перетащите мышью связанное поле одной таблицы на совпадающее поле в другой. Можно также удалить объединение, щелкнув правой кнопкой мыши линию объединения и выбрав команду Удалить (Delete).

231

Примечание

Если вы добавляете две несвязанные таблицы, программа Access пытается угадать связь, чтобы помочь вам. Если она находит поле с одинаковыми типами данных и именем в обеих таблицах, она добавляет связь для этих полей. Подобное действие зачастую совсем не то, что вам нужно — например, у многих таблиц есть общее поле Код (ID). Однако если вы строго соблюдаете правила проектирования БД, приведенные в разд. "Шесть правил проектирования БД" главы 2, у связанных полей имена в разных таблицах слегка отличаются, например ID и CustomerID. Если программа все же предлагает несуществующую связь, просто удалите ее, прежде чем выполнять нужное объединение.

На профессиональном уровне. Сравнение: отношения и объединения

Важно понимать различия между отношением или связью и запросом с операцией объединения.

Отношение — постоянная связь между двумя таблицами, хранящаяся в БД. Когда создается отношение в БД, есть возможность включить режим обеспечения целостности данных: набора правил, препятствующих проникновению противоречивых данных в связанные таблицы (см. разд. "Целостность на уровне ссылок " главы 5).

Объединение — операция запроса, позволяющая соединять связанные данные из двух таблиц в одном результирующем наборе. Объединение не влияет на то, как вы вводите и редактируете объединенные данные в базовых таблицах.

Если отношение установлено, Access считает, что вы хотите использовать операцию объединения для связи этих таблиц в запросе — единственное действие, имеющее смысл.

После того как вы поместили две таблицы в окно Конструктора запросов и определили операцию объединения, можно выбирать нужные вам поля из обеих таблиц. Можно также добавить условия отбора записей и задать порядок их сортировки, как в запросе любого другого типа. На рис. 6.18 показан пример запроса, использующего операцию объединения, а на рис. 6.19 — результат выполнения этого запроса.

Примечание

Если у вас две таблицы, легко забыть, что вы выводите на экран. Если объединяются таблицы Orders и Customers, а затем из каждой выбираются поля, что вы получите в результате: список заказов или список клиентов? Ответ прост — вы получаете список заказов, дополненный информацией о клиентах. Запросы со связанными таблицами всегда обрабатывают таблицу-потомок и берут дополнительную информацию из таблицы-родителя.

Примечание

При выполнении объединения вы видите повторяющуюся информацию. Если объединяются таблицы Customers и Orders, вы видите имя и фамилию самого активного клиента рядом с несколькими заказами. Но при этом правило запрета дублирующихся данных не нарушается. Несмотря на то, что сведения о клиенте появляются в нескольких местах на листе данных с результатами запроса, в таблице Customers они сохраняются всего один раз.

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

232

Рис.6.18. Этот запрос отображает данные из таблиц Orders и Customers. Неважно, из какой таблицы первое поле – в любом случае вы создаете список заказов с дополнительными сведениями о клиентах. Обратите внимание на строку Имя таблицы (Table) (под строкой Поле), указывающую на таблицу, из которой в запрос попадает каждое поле

Рис.6.19. Вы легко можете при беглом просмотре увидеть, кто что заказал. Столбец ID содержит идентификационный номер заказа (хотя вы могли бы отобразить идентификационные номера как таблицы

Customers, так и таблицы Orders)

233

Например, можно применить запрос с объединением для получения списка заказов (из дочерней таблицы) и дополнения каждой записи информацией о клиенте, сделавшем заказ. Независимо от способа объединения вы никогда не получите список клиентов с присоединенной информацией о заказе — в этом нет смысла, поскольку каждый клиент может сделать много заказов.

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

Примечание

Когда используется несколько таблиц, всегда есть риск наличия одноименных полей в обеих таблицах. Такая возможность не страшна, если вы не собираетесь отображать эти поля в вашем запросе, но если это не так, возможны проблемы. Единственный способ различить поля — переименовать одно из них на листе данных с результатами запроса. Из примечания "Малоизвестная или недооцененная возможность, Переименование поля в запросе" в разд. "Определение вычисляемого поля" главы 7 вы узнаете, как это сделать с помощью вычисляемого поля.

На профессиональном уровне.

Изменение данных при использовании запроса с объединением

Следует соблюдать осторожность при изменении данных в запросе, применяющем операцию объединения. Проблем не возникнет, если вы захотите изменить детали из таблицыпотомка. В примере на рис. 6.19 достаточно легко изменить поля DatePlaced или StatusID в записи о заказе.

Но что произойдет, если вы измените одно из значений таблицы-родителя, например, имя или фамилию клиента? Очевидно, что сведения об одном и том же клиенте могут выводиться в запросе несколько раз. (Например, в запросе на рис. 6.19 отображены два заказа клиента с именем Toby.) Если изменить имя в одном месте, программа Access автоматически изменит информацию в таблице Customers и затем обновит весь запрос. Таким образом, если вы замените "Toby" на "Топу" на рис. 6.19, Access обновит вторую и третью строки на листе данных.

Проблема возникает, когда вы хотите изменить связь между записью о заказе и записью клиента. Например, вы хотите отредактировать заказ, сделанный Toby, так, чтобы в БД было записано, что этот заказ сделан клиентом Lisa. Но этого сделать невозможно с помощью редактирования в запросе полей FirstName и LastName. (Если вы отредактируете имя и фамилию, то просто измените запись о Toby в таблице Customers.) Вместо этого вам нужно откорректировать поле CustomerID в таблице Orders так, чтобы оно указывало на нужного клиента. Но в запрос, показанный на рис. 6.19, иоле CustomerID не включено, поэтому изменить связь невозможно.

Внешние объединения

В запросах, которые вы видели в предыдущем примере, используются операции, которые специалисты БД называют внутренним объединением (inner join). Внутренние объединения выводят только связанные записи — другими словами, записи, встречающиеся в обеих таблицах. Если выполнить запрос к таблицам Customers и Orders, вы не увидите клиентов, не сделавших

234

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

Customers).

Внешние объединения (outer join) более емкие — они включают все результаты внутреннего объединения плюс оставшиеся в одной из таблиц (по вашему выбору) несвязанные записи. Очевидно, что эти несвязанные записи выводятся в окне результатов запроса с некоторыми пропущенными значениями, соответствующими пропущенным данным, которые должна была бы предоставить таблица.

Предположим, что вы выполняете внешнее объединение таблиц Orders и Customers, а затем настраиваете его так, чтобы выводились все записи о заказах. Все заказы, не связанные с записью о клиенте, появятся в нижней части списка и будут иметь незаполненные значения во всех полях со сведениями о клиенте (таких как FirstName и LastName) — табл. 6.1.

Таблица 6.1. Результат внешнего объединения таблиц Orders и Customers: все записи о заказах

FirstName

LastName

ID

DatePlaced

StatusID

Stanley

Lem

7

13-Jun-07

Cancelled

Toby

Grayson

4

03-NOV-06

Returned

Toby

Grayson

6

03-Nov-06

Shipped

 

 

18

01-Jan-08

In Progress

 

 

19

01 -Jan-08

In Progress

В данном конкретном примере нет смысла в существовании заказов, не связанных с конкретным клиентом. (На самом деле, скорее всего, это некорректно введенный заказ.) Если вы подозреваете наличие проблемы, внешнее объединение поможет устранить ее.

Подсказка

Вы можете помешать появлению записей-сирот с данными о заказе, сделав поле

CustomerID обязательным (см. разд. "Запрет незаполненных полей" главы 4) и обеспечив ссылочную целостность (см. разд. "Целостность на уровне ссылок" главы 5).

Вы также можете выполнить внешнее объединение таблиц Orders и Customers, которое отображает все записи о клиентах. В этом случае в конце результатов запроса вы увидите все несвязанные записи о клиентах с соответствующими пустыми полями, которые должны были бы содержать сведения о заказах (табл. 6.2).

Таблица 6.2. Результат внешнего объединения таблиц Orders и Customers: все записи о клиентах

FirstName

LastName

ID

DatePlaced

StatusID

Stanley

Lem

7

13-Jun-07

Cancelled

 

 

 

 

 

Toby

Grayson

4

03-NOV-06

Returned

Toby

Grayson

6

03-Nov-06

Shipped

235

Таблица 6.2 (окончание)

FirstName

LastName

ID

DatePlaced

StatusID

Ben

Samatara

 

 

 

 

 

 

 

 

Goosey

Mason

 

 

 

Tabasoum

Khan

 

 

 

В данном случае запрос с внешним объединением выбрал трех отстающих. Хотите знать, как добавить внешнее объединение в ваш запрос? Начните с внутреннего объединения (которое программа Access добавляет автоматически, см. разд. "Объединение таблиц в запросе" ранее в этой главе), а затем преобразуйте его во внешнее. Для этого просто щелкните правой кнопкой мыши линию объединения, связывающую две таблицы в окне Конструктора, и выберите команду Параметры объединения (Join Properties) (или дважды щелкните кнопкой мыши эту линию). На экране появится одноименное диалоговое окно (рис. 6.20), позволяющее изменить тип используемого вами объединения.

Рис. 6.20. Выбор первого переключателя Объединение только тех записей, в которых связанные поля обеих таблиц совпадают приводит к выполнению операции стандартного внутреннего объединения. Два оставшихся переключателя позволяют создать внешнее объединение, включающее все несвязанные строки одной из двух таблиц

Поиск несвязанных записей

Внутренние объединения — гораздо более распространенный тип объединений. Но внешние объединения позволяют создать, по крайней мере, один важный тип запроса: запрос, отслеживающий несвязанные записи (unmatched records).

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

Для выполнения такого запроса начните с запроса с внешним объединением, включающего все записи о клиентах. Затем добавьте один ингредиент: условие отбора, выбирающее записи без кода (ID) заказа. Технически это неопределенные (null) или пустые значения.

236

Рис. 6.21. В этом запросе сочетаются внешнее объединение и условие отбора, которому соответствуют только несвязанные записи о клиентах. Обратите внимание на то, что флажок Вывод на экран сброшен. Это сделано потому, что поле ID применяется в условии отбора, но в его присутствии на листе данных с результатами нет никакой необходимости

Рис. 6.22. В этом примере список продуктов усилен данными о категории продукта и сведениями о поставщике. Таблица Products — потомок как таблицы ProductCategories, так и таблицы Suppliers (поставщики), таким образом, данный запрос без усилий использует обе эти таблицы

237

Далее приведено нужное условие фильтрации, которое следует поместить в строке Условие отбора поля ID таблицы Orders:

IS Null

Теперь, когда программа Access выполнит запрос, она включит только записи клиентов, не связанные с записями в таблице заказов. На рис. 6.21 показан этот запрос в Конструкторе.

Множественные объединения

Как только вы освоились с внутренними и внешними объединениями, Access подбрасывает вам новую функциональную возможность. Многие запросы не ограничиваются одним объединением. Они используют три, четыре и больше объединений для соединения данных из многих связанных таблиц. Несмотря на то, что поначалу это кажется устрашающим, ничего сложного в этом нет.

Рис. 6.23. Если вы хотите выяснить, кто заказал каждый продукт, вам понадобится связанная таблица Orders, а затем придется перейти к связанной таблице Customers Даже если вы не хотите отображать какие-либо данные из таблицы Orders, вам все равно не обойтись без этого двухшагового процесса. На верхнем рисунке показан запрос, реализующий этот процесс, а на нижнем — результат, который вы получите после выполнения запроса

238

Множественные объединения — всего лишь способ включения дополнительной связанной информации в ваш запрос. При наличии нескольких объединений каждое из них выполняется точно так же, как если бы оно было одним в запросе. Для использования множественных объединений добавьте в запрос все нужные вам таблицы с помощью диалогового окна Добавление таблицы, убедитесь, что между таблицами появились линии объединения и затем выберите, какие хотите, поля. Программе Access почти всегда хватает интеллекта, чтобы понять, что вы собираетесь делать.

На рис. 6.22 показан пример, в котором у таблицы-потомка два родителя, способных внести некоторую дополнительную информацию.

Рис. 6.24. Вы видите, как определить список курсов, содержащий рядом с каждым курсом имя и фамилию преподавателя, ведущего курс. На верхнем рисунке показана нужная вам структура запроса, а на нижнем — результат

Иногда нужная вам информация находится в таблице, которая непосредственно не связана с основной таблицей запроса. Обратите внимание на таблицу OrderDetails, которую компания Boutique Fudge использует для перечисления всех товаров в заказе клиента. Сама по себе таблица OrderDetaits связана не с клиентом, заказавшим товары, а со связанной

239

записью о заказе (см. разд. "Заказ товаров" главы 5, в котором обсуждается этот проект БД). Если вы хотите получить сведения о том, кто заказал каждый товар, следует добавить в запрос таблицы OrderDetails, Orders и Customers, как показано на рис. 6.23.

Множественные объединения незаменимы, если у вас есть отношение "многие-ко-многим" со связующей таблицей (см. разд. "Отношение "многие-ко-многим"" главы 5), как между преподавателями и курсами. Как вы помните из главы 5, музыкальная школа Cacophone Studios использует промежуточную таблицу для отслеживания назначений преподавателей для ведения конкретных курсов. Если вы хотите получить список учебных курсов, дополненный именем и фамилией преподавателя, ведущего курс, придется создать запрос с тремя таблицами: Classes, Teachers и Teachers_Classes (рис. 6.24).

240

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]