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

Внутренние соединения возвращают результат, когда в обеих таблицах есть хотя бы одна строка, соответствующая условиям соединения. Внутренние соединения исключают строки, не соответствующие ни одной строке в другой таблице. Однако внешние соединения возвращают все строки хотя бы из одной таблицы или представления, упомянутых в предложении 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 AdventureWorks2008R2;
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 AdventureWorks2008R2;
GO
SELECT st.Name AS Territory, sp.BusinessEntityID
FROM Sales.SalesTerritory st 
RIGHT OUTER JOIN Sales.SalesPerson sp
ON st.TerritoryID = sp.TerritoryID ;

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

Territory BusinessEntityID

-------------------------------------------------- -------------

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)

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

USE AdventureWorks2008R2;
GO
SELECT st.Name AS Territory, sp.BusinessEntityID
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 AdventureWorks2008R2;
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 ;