Работа с внешними соединениями
Внутренние соединения возвращают результат, когда в обеих таблицах есть хотя бы одна строка, соответствующая условиям соединения. Внутренние соединения исключают строки, не соответствующие ни одной строке в другой таблице. Однако внешние соединения возвращают все строки хотя бы из одной таблицы или представления, упомянутых в предложении 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 ;
См. также