- •Часть 2
- •Часть 2
- •Содержание
- •1. Конструктор запросов 4
- •2. Запрос на выборку. 13
- •1. Конструктор запросов
- •Создание выражений с помощью Построителя выражений
- •2. Запрос на выборку.
- •2.1. Запрос, основанный на одной таблице и использующий простое условие
- •2.2. Простая выборка из двух связанных таблиц.
- •2.3. Запрос, использующий вычисляемые поля
- •2.4. Запрос с группировкой
- •2.5. Запрос, использующий связь таблицы с самой собой (рекурсивное соединение)
- •2.6. Запрос, использующий две ссылки на одну таблицу
- •2.7. Выборка повторяющихся записей
- •2.8. Поиск несовпадающих записей
- •2.9. Другие сведения, полезные при разработке запросов
- •3. Запрос на удаление записей.
- •3.1. Запрос на удаление всех записей из таблицы (очистка таблицы)
- •3.2. Запрос на удаление с ограничением числа удаляемых записей
- •3.3. Запрос на удаление с применением внешнего объединения таблиц
- •4. Запрос на добавление записей в существующую таблицу
- •4.1. Запрос на добавление записей во временную таблицу текущей базы данных
- •4.2. Запрос на добавление записей во временную таблицу внешней базы данных
- •5. Запрос на обновление записей в таблице.
- •5.1. Простой запрос на обновление записей
- •5.2. Запрос на обновление полей нескольких связанных таблиц.
- •6. Запросы на объединение.
- •6.1. Запрос на объединение, связывающий воедино однотипные таблицы из различных баз данных.
- •7. Перекрестные запросы
- •7.1. Создание перекрестного запроса при помощи мастера
- •7.2. Сознание перекрестного запроса при помощи конструктора запросов
- •8. Запросы с параметрами
- •9. Подчиненные запросы
- •9.1. Использование подчиненных запросов в выражениях для условий отбора записей
- •9.2. Использование подчиненных запросов в определении полей основного запроса.
- •10. Свойства полей запросов
- •11. Свойства запросов
2.5. Запрос, использующий связь таблицы с самой собой (рекурсивное соединение)
Допустим, нужно получить выборку сотрудников, заказов и клиентов, для которых дата размещения заказов совпадает с датой исполнения за 1998 год. Для этого откройте новый запрос в режиме конструктора и добавьте в него таблицы Заказы и Сотрудники, причем Заказы — два раза. В результате система автоматически присвоит для копии таблицы Заказы имя Заказы_1. К уже имеющейся постоянной связи между таблицами Заказы и Сотрудники нужно добавить связь между таблицами Заказы и Заказы_1 по полям ДатаРазмещения и ДатаИсполнения. Такая связь называется рекурсивным соединением. Для того чтобы запрос работал правильно, нужно также добавить связь по полям КодЗаказа таблиц Заказы и Заказы_1.
В первое поле бланка запроса введите определение: Сотрудник: [Фамилия] & " " & [Имя] и добавьте поля Должность из таблицы Сотрудники и КодЗаказа, КодКлиента и Дата Размещения из таблицы Заказы. Для полей Сотрудник и Дата Размещения установите порядок сортировки по возрастанию и для поля ДатаРазмещения укажите условие: Between #01.01.98# And #31.12.98#. Полученный запрос изображен на рис. 2.5.
|
|
|
Рис 2.5. Запрос, использующий рекурсивное соединение таблиц.
Пояснения
а). При построении этого запроса есть один тонкий момент, незнание которого может привести к получению ошибочной итоговой выборки. Если между таблицами Заказы и Заказы_1 будет только одна связь по полям ДатаРазмещения и ДатаИсполнения,, то будут выбираться те записи, в которых оба поля совпадают, в том числе и для совершенно разных заказов.
Для того чтобы ограничиться заказами, для каждого из которых поля ДатаРазмещения и Дата Исполнения имеют одинаковые значения, нужно связать также поля КодЗаказа таблиц Заказы и Заказы_1.
б). Изначально таблица Заказы учебной базы данных Борей не имеет ни одной записи, содержащей одинаковые значения в полях ДатаРазмещения и ДатаИсполнения. Для того чтобы продемонстрировать способ использования рекурсивной связи, пришлось вручную подкорректировать даты одной из записей.
Если добавить в бланк запроса сначала дважды таблицу Заказы и затем — Сотрудники, то конструктор также автоматически свяжет таблицу Сотрудники с копией таблицы Заказы — Заказы_1 по полю КодСотрудника. Эта связь лишняя и ее нужно убрать. Если добавлять в макет запроса таблицы в обратной последовательности, то лишняя связь создана не будет.
2.6. Запрос, использующий две ссылки на одну таблицу
Иногда возникает проблема, сводящаяся к тому, что итоговый запрос должен содержать несколько полей, ссылающихся на одну и ту же таблицу-справочник. Типичным примером указанной ситуации является документ (накладная) на перемещение товарно-материальных ценностей (ТМЦ) с одного склада предприятия на другой. Принципы построения реляционных баз данных требуют, чтобы в полях ИсходныйСклад и СкладНазначения хранились ссылки на соответствующее поле таблицы-справочника Список складов. Создавая запрос, отображающий позиции всех таких накладных, мы можем одну из ссылок связать с таблицей-справочником Список складов, чтобы в итоговой выборке было представлено не абстрактное число, а, например, полное наименование склада, фамилия материально-ответственного лица и другая соответствующая информация. Однако, если связать с таблицей Список складов и вторую ссылку, то в итоговую выборку попадут только те записи, в которых ИсходныйСклад и Склад Назначения совпадают.
Прежде чем приступить к описанию решения такой проблемы, следует проделать несколько предварительных действий. Перейдите на вкладку Таблицы окна базы данных и создайте две новых таблицы: Список отделов и Список сотрудников по отделам. Первая таблица должна содержать следующие поля: Номер числового типа, размер — длинное целое; Отдел — текстового типа; Начальник — числового типа, размер — длинное целое. Далее перейдите в режим просмотра и введите в таблицу информацию в соответствии с рис. 2.6. Эта таблица будет служить для распределения всех сотрудников по различным отделам.
Вторая таблица, Список сотрудников по отделам, должна содержать два поля — Сотрудник и Отдел. Оба поля должны быть числового типа, размер — длинное целое. Использование этой таблицы является ярким примером того, как можно расширить уже готовую структуру базы данных, при этом, не нарушая ее. С другой стороны, эта таблица является примером применения связей многие-ко-многим, поскольку будет служить для связывания многих записей из таблицы Сотрудники со многими записями из таблицы Список отделов. После окончания конструирования перейдите в режим просмотра и заполните таблицу информацией в соответствии с рис. 2.6.
|
|
Рис 2.6. Вспомогательные таблицы Список отделов и Список сотрудников
Далее перейдите на вкладку Запросы окна базы данных и создайте новый запрос, открыв его в режиме конструктора. Добавьте в его макет таблицы Список отделов, Список сотрудников по отделам и таблицу Сотрудники — дважды. Между таблицами создайте следующие связи: между полем Начальник таблицы Список отделов и полем КодСотрудника таблицы Сотрудники; между полем Номер таблицы Список отделов и полем Отдел таблицы Список сотрудников по отделам; между полем Сотрудник таблицы Список сотрудников по отделам и полем КодСотрудника таблицы Сотрудники!.
После этого перетащите в бланк запроса поле Отдел из таблицы Список отделов, в определение второго поля введите текст: Сотрудник: Сотрудники_1.Фамилия & " " & Сотрудники_1.Имя, а в определение третьего — Начальник:Сотрудники.Фамилия & " " & Сотрудники.Имя. В заключение установите для первых двух полей сортировку По возрастанию. Получившийся запрос представлен на рис. 2.7.
|
|
Рис 2.7. Запрос, использующий две ссылки на одну таблицу.
Пояснения
а). Если из бланка запроса (см. рис. 2.7) удалить копию таблицы Сотрудники и связать поля Начальник таблицы Список отделов и Сотрудник таблицы Список сотрудников по отделам с полем КодСотрудника таблицы Сотрудники, то в итоговой выборке будет только список руководителей отделов. Действительно, установленные таким образом связи подразумевают, что отбираться будут только те записи из трех таблиц, в которых значения всех трех полей совпадают. Получается замкнутый круг. Чтобы разорвать этот круг и применяются копии таблиц. В описываемом примере существует одно лишнее поле, для которого в макет запроса была добавлена одна копия таблицы. Если в запросе будет два лишних поля — то нужно будет использовать две копии таблицы, и т.д.
б). Вспомогательная таблица Список сотрудников по отделам используется для создания связи типа многие-ко-многим между таблицами Список отделов Сотрудники. В таких таблицах обычно содержатся исключительно ключевые поля связываемых таблиц.
в) В приведенном примере для связывания всех таблиц использовались временные связи.
г) Обратите внимание на то, как в строке оператора SQL в предложении FROM вводится копия таблицы Сотрудники:
Сотрудники AS Сотрудники_1
Эта конструкция указывает на то, что далее в операторе SQL имя Сотрудники_1 будет употребляться как синоним имени таблицы Сотрудники. Такие конструкции могут применяться не только в описываемом здесь случае. В частности, если в запросе используются длинные наименования таблиц, то можно в предложении FROM для каждой такой таблицы указать синоним, состоящий всего из одной или нескольких букв, и дальше пользоваться исключительно синонимами. Обычно этим пользуются в СУБД, где приходится вводить текст оператора SQL вручную (нет такого удобного средства как конструктор запросов), или существуют серьезные ограничения на длину SQL-оператора.