Программирование >>  Sql: полное руководство 

1 ... 48 49 50 [ 51 ] 52 53 54 ... 264


SELECT * FROM BOYS

будучи примененным к таблице girls, состоящей из трех строк, и таблице boys, содержащей две строки, возвратит таблицу из пяти строк. Каждая из них в точности соответствует одной из строк таблицы girls либо boys. В таблице результатов запроса будет два столбца, name и city, как и в обеих исходных таблицах.

Расширенный запрос на объединение к этим же таблицам записывается так:

SELECT *

FROM GIRLS UNION JOIN BOYS

Таблица результатов такого запроса снова будет содержать пять строк, каждая из которых образована в точности одной строкой из таблиц girls либо boys. Но, в отличие от предыдущего случая, количество столбцов в полученной таблице будет четыре, а не два, - все столбцы из первой таблицы плюс все столбцы из второй таблицьг Здесь можно найти определенное сходство с внешним объединением. В каждой строке таблицы результатов запроса, построенной на основе строки из таблицы girls, значения в столбцах, взятых из таблицы girls, будут оставлены без изменений; все остальные столбцы (из таблицы boys) заполняются значениями null. Точно так же в каждой строке из таблицы boys значения в столбцах этой таблицы остаются неизменными, а столбцы из таблицы girls заполняются значениями null. Если мы обратимся к таблице 7.2, в которой описаны правила построения внешнего объединения, что увидим, что результаты расширенного запроса на объединение можно получить, если выполнить пункты 2 и 3, а пункт 1 пропустить.

В заключение полезно будет провести сравнение различий между наборами результатов, получаемыми при вьшолнении объединений различных видов (рис. 7.14). Из рисунка видно, что при объединении двух таблиц, tbli с числом строк т и tbl2 с числом строк л, происходит следующее:

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

внутреннее объединение вернет таблицу, состоящую из некоторого числа строк, г, причем г < тхп. Внутреннее объединение является подмножеством декартового произведения. Оно образуется путем удаления тех строк из таблицы произведения, которые не удовлетворяют условию отбора;

левое внешнее объединение вернет таблицу, содержащую все строки внутреннего объединения плюс расширенные значениями null строки таблицы tbl1, не удовлетворяющие условию отбора;

правое внешнее объединение вернет таблицу, содержащую все строки внутреннего объединения плюс расширенные значениями null строки таблицы tbl2, не удовлетворяющие условию отбора;

полное внешнее объединение вернет таблицу, содержащую все строки внутреннего объединения плюс расширенные значениями null строки таблиц tbli и tbl2, не удовлетворяющие условию отбора;

расширенный запрос на объединение вернет таблицу, содержащую все строки таблиц tbl1 и tbl2, расширенные значениями null.



Полное внешнее объединение

Строки TBL1, удовлетворяющие условию отборв;

расширены значениями NULL

Правое внешне;, объединение

Строки TBL1, не удовлетворяющие

условию отбора;

расширены значениями NULL

Пары строкTBL1

и TBL2, удовлетворяющие условию отбора

Внутреннее , объединение \

Пары строк TBL1

и TBL2, не удовлетворяющие условию отборв

Перекрестное V объединение

Строки TBL2, удовлетворяющие условию отбора;

расширены значениями NULL

Строки TBL2, не удовлетворяющие

условию отбора,

расширены значениями NULL

Расширенный запрос на объединение

Таблица TBL1. расширенная значениями NULL (m строк)

Все пары строк TBL1 и TBL2 (т X п строк)

Таблица TBL2, расширенная значениями NULL (п строк)

Рис. 734. Сравнение различныгвидов объединения в SQL2

Многотабличные объединения в стандарте SQL2

Одно из важных преимуществ расщиренного предложения from заключается в том, что оно дает единый стандарт для определения всех возможных видов объединений. Другим, даже еще более значительным преимуществом этого предложения является то, что оно обеспечивает четкую спецификацию объединений трех и более таблиц. При построении столь сложных объединений любое выражение объединения из числа изображенных на рис. 7.13 и описанных в предыдущих параграфах может быть заключено в круглые скобки. Результирующее выражение, в свою очередь, можно использовать для создания других выражений объединения, как если бы оно было простой таблицей. Точно так же, как SQL позволяет с помощью круглых скобок комбинировать различные арифметические операции (+,-,* и /), стандарт SQL2 дает возможность создавать сложные выражения для объединений.

Чтобы привести пример многотабличного объединения, предположим, что к таблицам girls и boys добавлена новая таблица parents, которая имеет три столбца; child Соответствует столбцу name в таблицах girls и boys ре Принимает значение father (отец) или mother (мать) pname Имя родителя

Строка в таблице girls или boys может иметь две связанные строки в таблице Parent, одна из которых определяет мать, а другая - отца, или может иметь только



одну из этих строк, или может совсем не иметь связанных строк, если отсутствуют данные о родителях ребенка. В таблицах girls, boys и parents в совокупности содержится достаточно богатый набор данных, чтобы обеспечить несколько примеров многотабличных запросов.

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

SELECT GIRLS.ЫАМЕ, РЫАМЕ, BOYS.NAME FROM (GIRLS INNER JOIN PARENTS ON PARENTS.CHILD = GIRLS.NAME) INNER JOIN BOYS

ON GIRLS.CITY = BOYS.CITY WHERE TYPE = MOTHER

Так как оба объединения являются внутренними, то девочки, не имеющие связанных строк в таблицах parents и boys, в таблицу результатов запроса не попадут. Модифицировав первую часть запроса в левое внешнее объединение, можно включить в результаты запроса строки, соответствующие девочкам, для которых отсутствует информация о матерях:

SELECT GIRLS.NAME, PNAME, BOYS.NAME FROM (GIRLS LEFT JOIN PARENTS

ON PARENTS.CHILD = GIRLS.NAME)

INNER JOIN BOYS

ON GIRLS.CITY = BOYS.CITY WHERE (TYPE = MOTHER ) OR (TYPE IS NULL)

В результатах этого запроса по-прежнему отсутствуют девочки, в одном городе с которыми не живет ни одного мальчика. Если их тоже нужно включить в запрос, следует и второе объединение сделать внешним;

SELECT GIRLS.NAME, PNAME, BOYS.NAME FROM (GIRLS LEFT JOIN PARENTS

ON PARENTS.CHILD = GIRLS.NAME) LEFT JOIN BOYS

ON GIRLS.CITY = BOYS.CITY WHERE (TYPE = MOTHER ) OR (TYPE IS NULL)

Следует обратить внимание на то, что левое внешнее объединение таблиц girls и parents создает одну дополнительную проблему. Если для какой-либо девочки отсутствует информация о матери, то не только столбец pname, но и столбец type будет равен null. Поэтому простая проверка

WHERE (TYPE = MOTHER )

для таких строк вернет значение null, и они не будут включены в результаты запроса. Но ведь это противоречит смыслу самого запроса! Для решения данной проблемы в предложение where добавлена вторая проверка на равенство столбца type значению null.

В качестве завершающего примера предположим, что вы опять, как в предыдущих случаях, хотите найти пары девочка/мальчик из одного и того же города, но на этот раз вьг>ютите еще и включить в таблицу результатов имя отца мальчика и имя матери девоЧки. Такой запрос требует четырехтабличного объединения (таблицы boys,



1 ... 48 49 50 [ 51 ] 52 53 54 ... 264

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика