Поделиться через


Работа с внешними соединениями

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

Для внешних соединений в предложении FROM SQL Server использует ключевые слова ISO:

  • LEFT OUTER JOIN или LEFT JOIN;

  • RIGHT OUTER JOIN или RIGHT JOIN;

  • FULL OUTER JOIN или FULL JOIN.

Работа с левыми внешними соединениями

Рассмотрим соединение таблиц Product и ProductReview по столбцам ProductID. В результате будут выведены только те продукты, для которых были написаны обзоры.

Чтобы включить в результаты все продукты, независимо от того, были ли написаны обзоры, используйте левое внешнее соединение ISO. Пример запроса:

USE AdventureWorks;
GO
SELECT p.Name, pr.ProductReviewID
FROM Production.Product p
LEFT OUTER JOIN Production.ProductReview pr
ON p.ProductID = pr.ProductID

Ключевые слова LEFT OUTER JOIN включают в вывод все строки таблицы Product независимо от того, есть ли для них соответствующие значения в столбце ProductID таблицы ProductReview. Обратите внимание на то, что в результатах, где для продукта нет соответствующего обзора, строки содержат значение NULL в столбце ProductReviewID.

Работа с правыми внешними соединениями

Рассмотрим соединение таблиц SalesTerritory и SalesPerson по столбцам TerritoryID. В результате будут выведены все территории, которым был назначен менеджер по продажам. Оператор правого внешнего соединения ISO, RIGHT OUTER JOIN, включает в результаты все строки второй таблицы независимо от того, есть ли для них совпадающие данные в первой таблице.

Чтобы включить в результаты всех менеджеров по продажам независимо от того, есть ли связанные с ними территории, используйте правое внешнее соединение ISO. Пример запроса Transact-SQL и результаты правого внешнего соединения:

USE AdventureWorks;
GO
SELECT st.Name AS Territory, sp.SalesPersonID
FROM Sales.SalesTerritory st 
RIGHT OUTER JOIN Sales.SalesPerson sp
ON st.TerritoryID = sp.TerritoryID ;

Ниже приводится результирующий набор.

Territory                                          SalesPersonID
-------------------------------------------------- -------------
NULL                                               268
Northeast                                          275
Southwest                                          276
Central                                            277
Canada                                             278
Southeast                                          279
Northwest                                          280
Southwest                                          281
Canada                                             282
Northwest                                          283
NULL                                               284
United Kingdom                                     285
France                                             286
Northwest                                          287
NULL                                               288
Germany                                            289
Australia                                          290

(17 row(s) affected)

Внешнее соединение может затем быть ограничено предикатом. В следующем примере используется то же правое внешнее соединение, но в него включены только территории с суммами продаж меньше $2 000 000:

USE AdventureWorks;
GO
SELECT st.Name AS Territory, sp.SalesPersonID
FROM Sales.SalesTerritory st 
RIGHT OUTER JOIN Sales.SalesPerson sp
ON st.TerritoryID = sp.TerritoryID 
WHERE st.SalesYTD < $2000000;

Дополнительные сведения о предикатах см. в разделе Предложение WHERE (Transact-SQL).

Работа с полными внешними соединениями

Чтобы сохранить в выводе не соответствующие друг другу строки из обеих таблиц, включив их в результаты соединения, используйте полное внешнее соединение. SQL Server предоставляет оператор полного внешнего соединения, FULL OUTER JOIN, включающий все строки из обеих таблиц вне зависимости от того, есть ли в них совпадающие значения.

Рассмотрим соединение таблиц Product и SalesOrderDetail по столбцам ProductID. В результате будут показаны только те продукты, на которые есть заказы. Оператор полного внешнего соединения ISO, FULL OUTER JOIN, включает в результаты все строки из обеих таблиц независимо от того, есть ли для них совпадающие данные в другой таблице.

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

USE AdventureWorks;
GO
-- The OUTER keyword following the FULL keyword is optional.
SELECT p.Name, sod.SalesOrderID
FROM Production.Product p
FULL OUTER JOIN Sales.SalesOrderDetail sod
ON p.ProductID = sod.ProductID
WHERE p.ProductID IS NULL
OR sod.ProductID IS NULL
ORDER BY p.Name ;