|
Программирование >> Sql: полное руководство
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,
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |