Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
УМП-БД.doc
Скачиваний:
17
Добавлен:
05.12.2018
Размер:
1.26 Mб
Скачать

Объединения с условием для отбора строк

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

В результате применения дополнительного условия поиска число строк в таблице результатов запроса уменьшилось. Согласно первому условию (MGR=EMPL_NUM), из таблиц OFFICES и SALESREPS отбираются пары строк, которые имеют соответствующее отношение предок/потомок; согласно второму условию, производится дальнейший отбор только тех пар строк, где плановый объем продаж превышает $600000.

Несколько связанных столбцов

Таблицы orders и products в учебной базе данных связаны парой составных ключей. Столбцы mfr и product в таблице orders вместе образуют внешний ключ для таблицы products и связаны с ее столбцами mfr_id и product_id соответственно. Чтобы объединить таблицы на основе такого отношения предок/потомок, необходимо задать обе пары связанных столбцов, как показано в данном примере:

Условие поиска показывает, что связанными парами строк таблиц orders и products являются те, в которых пары связанных столбцов содержат одни и те же значения. Объединения посредством нескольких столбцов распространены меньше, чем объединения посредством одного столбца, и обычно встречаются в запросах с составными внешними ключами, как в приведенном выше примере.

Запросы на чтение к трем и более таблицам

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

В этом запросе используются два внешних ключа таблицы orders. Столбец cust является внешним ключом для таблицы customers; он связывает каждый заказ с клиентом, сделавшим его. Столбец rep является внешним ключом для таблицы salesreps, связывая каждый заказ со служащим, принявшим его. Проще говоря, запрос связывает каждый заказ с соответствующими клиентом и служащим.

А вот еще один запрос к трем таблицам, в котором используется другая комбинация отношений предок/потомок:

В первом отношении снова используется столбец cust из таблицы orders в качестве внешнего ключа для таблицы customers. Во втором отношении используется столбец custjrep из таблицы customers в качестве внешнего ключа для таблицы salesreps. Проще говоря, данный запрос связывает каждый заказ с клиентом, а каждого клиента — с закрепленным за ним служащим.

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

Фактически, он на один шаг расширяет последовательность объединения в предыдущем запросе, связывая заказ с клиентом, клиента — с закрепленным за ним служащим, а служащего — с его офисом.

Прочие объединения таблиц по равенству

Огромное множество многотабличных запросов основано на отношения предок/потомок, но в SQL не требуется, чтобы связанные столбцы представляли собой пару "внешний ключ — первичный ключ". Любые два столбца из двух таблиц могут быть связанными столбцами, если только они имею сравнимые типы данных. Вот пример запроса, в котором связанными столбцами являются столбцы с датами:

Результатами запроса являются пары строк из таблиц orders и salesreps, имеющие одинаковые значения в столбцах ORDER_DATE И HIRE_DATE. Эти столбцы не являются ни внешним ключом, ни первичным ключом, да и вообще отношение между строками этих пар, надо признать, довольно странное: общее у заказов и служащих только то, что они появились в компании в один день. Тем не менее, SQL с готовностью объединяет таблицы в соответствии с запросом.

Связанные столбцы, подобные приведенным в данном примере, создают между двумя таблицами отношение "многие-ко-многим". Может быть получено много заказов в день приема на работу какого-нибудь служащего, и в день получения какого-нибудь заказа на работу может быть принято несколько служащих. В нашем примере 12 октября 1989 года было получено три заказа (112968, 112975 и 112979), и в тот же день на работу было принято двое служащих (Ларри Фитч и Мэри Джонс). Три заказа и двое служащих дают шесть строк в таблице результатов запроса.

Отношение "многие-ко-многим" отличается от отношения "один-ко-многим", создаваемого, когда в качестве связанных столбцов используются первичный и внешний ключи. Можно подвести следующие итоги:

• В объединении, созданном путем связи первичного ключа с внешним ключом, всеща существует отношение "один-ко-многим" (предок/потомок).

• В других объединениях также могут существовать отношения "один-ко-многим", если по крайней мере в одной таблице связанный столбец содержит уникальные значения во всех строках.

• В общем случае в объединениях, созданных на основе произвольных связанных столбцов, существуют отношения "многие-ко-многим". Обратите внимание на то, что отличия трех этих ситуаций не влияют на форму записи оператора select, выражающего объединение. Объединения всех трех типов записываются одним и тем же способом: в предложение where включается операция сравнения связанных столбцов. Тем не менее, сделанные выводы полезны для понимания того, как запрос, сформулированный на естественном языке, превратить в правильный оператор select.

ОБЪЕДИНЕНИЕ ТАБЛИЦ ПО НЕРАВЕНСТВУ

Термин "объединение" применяется к любому запросу, который объединяет данные из двух таблиц базы данных путем сравнения значений в двух столбцах этих таблиц. Самыми распространенными являются объединения^ созданные на основе равенства связанных столбцов (объединения по равенству). Кроме того, SQL позволяет объединять таблицы с помощью других операций сравнения. В приведенном ниже примере для объединения таблиц используется операция сравнения "больше ч^м" (>):

Как и во всех запросах к двум таблицам, каждая строка результатов запроса получается из пары строк, в данном случае содержащихся в таблицах salesreps и offices. Условие поиска

QUOTA > TARGET

отбирает пары строк, в которых значение столбца quota из таблицы salesreps превышает значение столбца target из таблицы offices. Обратите внимание: выбранные из таблиц salesreps и offices пары строк связаны только таким образом; в частности, не требуется, чтобы строка таблицы salesreps представляла служащего, который работает в офисе, представленном строкой таблицы offices. Следует признать, что данный пример имеет несколько искусственный характер и является иллюстрацией того, почему столь мало распространены объединения по неравенству. Однако они могут оказаться полезными в приложениях, предназначенных для поддержки принятия решений, и в других приложениях, исследующих более сложные взаимосвязи в базе данных.

ОСОБЕННОСТИ МНОГОТАБЛИЧНЫХ ЗАПРОСОВ

Многотабличные запросы, рассмотренные до сих пор, не требовали применения специальных синтаксических форм или каких-либо других особенностей языка SQL помимо тех, что использовались для создания однотабличных запросов. Однако некоторые многотабличные запросы нельзя создать без использования дополнительных особенностей языка SQL, описанных в следующих параграфах. В частности:

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

• В многотабличных запросах особый смысл имеет выбор всех столбцов

(SELECT *).

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

• В предложении from используются псевдонимы таблиц, чтобы упростить полные имена столбцов и обеспечить однозначность ссылок на столбцы в самообъединении.

ПОЛНЫЕ ИМЕНА СТОЛБЦОВ

В учебной базе данных имеется несколько случаев, когда две таблицы содержат столбцы с одинаковыми именами. Например, столбцы с именем sales имеются в таблицах offices и salesreps. В столбце sales таблицы offices содержится объем продаж на текущую дату года для каждого офиса; в аналогичном столбце таблицы salesreps содержится объем продаж на текущую дату года для каждого служащего. Обычно с этими двумя столбцами затруднений не возникает, поскольку в предложении from задается соответствующая таблица, как в следующих примерах:

Хотя в формулировке запроса на естественном языке подразумевается столбец sales из таблицы salesreps, созданный запрос SQL является неоднозначным. Чтобы исключить разночтения, при указании столбцов необходимо использовать их полные имена. Полное имя столбца содержит имя столбца и имя таблицы, в которой он находится. Полные имена двух столбцов sales в учебной базе данных будут такими:

OFFICES.SALES и SALESREPS.SALES

В операторе SELECT вместо простых имен столбцов всегда можно использовать полные имена. Таблица, заданная в полном имени столбца, должна, конечно, соответствовать одной из таблиц, заданных в предложении from. Вот исправленный вариант предыдущего запроса, в котором используется полное имя столбца:

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