|
Программирование >> Программирование баз данных
Многие разработчики, использующие язык SQL, осваивают лишь внутреннее соединение, осуществляемое с помощью конструкции INNER JOIN, но так и не заходят глубже; иными словами, многие разработчики просто не умеют пользоваться разновидностью оператора соединения с конструкцией OUTER. Цели, которые позволяет достичь применение конструкции OUTER JOIN, часто достижимы с помощью других методов. Разработчики зачастую просто забывают о том, что может использоваться подобная конструкция. Еще раз отметим, что при использовании конструкции INNER JOIN исключаются все строки, не соответствующие всем заданным критериям, а при использовании конструкции OUTER, а также, как будет показано ниже в этой главе, конструкции FULL JOIN существует возможность включить в результирующий набор строки, которые соответствуют хотя бы одному из заданных критериев. Иногда с помощью конструкции OUTER JOIN удается легко решить задачи, которые на первый взгляд кажутся очень сложными, поэтому очень жаль, что многие не умеют применять эти конструкции. Кроме того, применение внешних запросов часто может привести к повышению производительности при их использовании вместо других способов организации работы, которые могут применяться для получения того же результата. В соединениях различаются стороны - левая и правая. Левой считается таблица, указанная в первую очередь, а правой - таблица, указанная после нее. Рассматривая операторы с конструкцией INNER JOIN, мы в основном не придавали этому различию значения, поскольку во внутреннем соединении обе стороны всегда рассматриваются на равных. Но когда речь идет о конструкциях OUTER JOIN, понимание того, что обработ ка левой таблицы происходит иначе, чем правой, становится буквально необходимым. Впервые сталкиваясь с этим различием, можно подумать, что в нем нет ничего сложного; и действительно, все обсторгг очень просто, но слишком часто встречаются ошибки в запросах, основанных на использовании конструкции OUTER JOIN, которые обусловлены тем, что не учитывается различие между левой и правой таблицами. Рассмотрим еще раз один из вариантов первой версии запроса, касающегося служащих и руководителей: SELECT е.EmployeeID, m.EmployeelD AS ManagerID FROM HumanResources.Employee e INNER JOIN HumanResources.Employee m ON e.ManagerlD = m.EmployeelD; Объем формируемых результатов не столь велик, но заслуживает внимания то, какое количество строк возвращает этот запрос; на компьютере автора это значение составило 289 строк (такое значение может быть получено после инсталляции базы данных AdventureWorks в конфигурации, предусмотренной по умолчанию). После этого внесем в запрос лишь некоторые изменения: SELECT е .Employee id, m.EmployeelD AS Manager ID FROM HumanResources.Employee e LEFT OUTER JOIN HumanResources.Employee m ON e.ManagerlD = m.EmployeelD; В данном случае указано, что должны быть включены все строки, относящиеся клевой стороне, LEFT, независимо от того, имеются ли для них соответствия в правой стороне. Применительно к рассматриваемому запросу можно отметить, что в нем сформулировано требование включить все строки с данными о служащих, а также те строки с данными о руководителях, для которых имеется соответствие. Проверка полученных результатов должна показать, что количество строк увеличилось на одну (в базе данных, которую использовал автор для выполнения рассматриваемого примера, количество строк составило 290). Изучите сами полученные данные и определите, сможете ли вы найти строку, которая не встречалась раньше. EmployeelD ManagerlD 109 NULL Если вам удастся определить такую строку, то вы обнаружите, что служащий с идентификационным номером 109 никому не подчиняется (по-видимому, это старший руководитель). Обратите особое внимание на то, как в СУБД SQL Server решается задача заполнения столбца данными, поступающими из таблицы, находящейся в правой стороне соединения, если искомые данные отсутствуют - вместо отсутствующих данных подставляется NULL-значение. В дальнейшем будет показано, как проводить поиск NULL-значений в одной из сторон соединения для обнаружения таких ситуаций, как от сутствие строк, согласующихся со строками в другой стороне соединения. Если данный вариант соединения будет заменен противоположным (путем перехода к применению конструкции RIGHT JOIN), то применительно к данному конкретному набору записей будет получен тот же результат, как и в запросе с конструкцией INNER JOIN, поскольку в правой стороне соединения (в той стороне, в которой представлены данные о руководителях) нет никаких данных, которых бы не было в левой стороне (где рассматриваются данные о служащих). Но это не означает, что правое соединение действует иначе, чем левое; только в этом случае рассматриваются все строки, находящиеся в правой стороне соединения, а в левой стороне остаются лишь те строки, для которых имеется соответствие. Полные соединения Полные соединения можно считать своего рода результатом совместного применения левого и правого соединений. Если применяется соединение с ключевым словом FULL, соответствующий оператор равносилен передаваемому СУБД SQL Server указанию, что в результаты должны быть включены все строки с обеих сторон соединения. В базе данных AdventureWorks трудно найти какие-либо действительно наглядные примеры, позволяющие продемонстрировать именно этот вариант соединения, но поскольку сами принципы применения полных соединений довольно просты, тем более для тех, кто уже ocbopui работу с внешними соединениями, подготовим только следующую сравнительно несложную демонстрацию: CREATE TABLE Film (FilmlD int PRIMARY KEY, FilmName varchar(20) NOT NULL, YearMade smallint NOT NULL CREATE TABLE Actors (FilmlD int NOT NULL, FirstName varchar(15) NOT NULL, LastName varchar(15) NOT NULL, CONSTRAINT PKActors PRIMARY KEY(FilmID, FirstName, LastName) INSERT INTO Film VALUES (1, My Fair Lady, 1964); INSERT INTO Film VALUES (2, Unforgiven , 1992); INSERT INTO Actors VALUES (1, Rex, Harrison); INSERT INTO Actors VALUES (1, Audrey, Hepburn); INSERT INTO Actors VALUES (3 , Anthony, Hopkins); Некоторые применяемые выше операторы еще не были описаны в данной книге, но в рассматриваемом примере это не имеет большого значения. Прежде всего, я надеюсь, что многие читатели уже имеют определенный уровень знаний (если же вам требуется освежить в памяти элементарные сведения, то рассмотрите возможность еще раз ознакомиться с книгой Программирование баз Microsoft SQL Server 2005. Базовый курс); кроме того, фактически в данном случае производится лишь подготовка образца для работы с изучаемыми в данном разделе полными соединениями, а подробные сведения о некоторых применяемых операторах будут приведены ниже в этой главе и в следующей. Подготовив необходимые данные, перейдем к выполнению следующего оператора FULL JOIN и изучению полученных результатов: SELECT * FROM Film f FULL JOIN Actors a ON f.FilmlD = a.FilmlD; Приведенные ниже результаты показывают, что применительно ко всем согласующимся данным выполнено соединение, полностью включены данные, которые присутствуют только в левой стороне (и на месте данных, которые не были обнаружены в правой стороне, приведены NULL-значения), а также включены все данные, присутствующие только в правой стороне (и, безусловно, вместо отсутствующих данных приведены NULL-значения). FilmlD FilmName YearMade FilmlD FirstName LastName 1 1 2 NULL My Fair Lady My Fair Lady Unforgiven NULL 1964 1 1964 1 1992 NULL NULL 3 Audrey Rex NULL Anthony Hepburn Harrison NULL Hopkins (4 row(s) affected) Перекрестные соединения Последний вариант операции соединения, рассматриваемый в данной главе (перекрестные соединения), существенно отличается от соединений других типов. Соединения CROSS JOIN отличаются от соединений других типов тем, что в них отсутствуют операции ON, а также тем, что в них происходит соединение каждой строки таблиц, находящихся с одной стороны от ключевого слова JOIN, с каждой строкой таблиц, находящихся с другой стороны от ключевого слова JOIN. Короче говоря, в конечном итоге формируется декартово произведение всех строк, заданных по обе стороны от ключевого слова JOIN. Операторы с конструкцией CROSS JOIN имеют такой же синтаксис, как и любые другие операторы JOIN, за исключением того, что в них используется ключевое слово CROSS (вместо INNER, OUTER или FULL), а конструкция ON отсутствует.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |