ВВЕРХ

SQL-Урок 11. Расширенное сочетание таблиц (OUTER JOIN)

В предыдущем разделе мы рассмотрели самые простые способы сочетания таблиц – с помощью предложений WHERE и INNER JOIN. Эти сочетания называются внутренними сочетаниями или сочетаниями по эквивалентности. Однако SQL имеет в своем арсенале гораздо больше возможностей совместить таблицы, а именно существуют и другие виды объединений: внешние сочетания, естественные сочетания и самосочетания. Но для начала рассмотрим, каким образом мы можем присваивать таблицам псевдонимы, поскольку в дальнейшем мы будем вынуждены использовать полные названия полей (Таблица.Поле), которыми без сокращений будет очень трудно оперировать из-за их большой длины.


1. Использование псевдонимов таблиц (Aliases)

В предыдущем разделе мы узнали, как можно использовать псевдонимы для ссылки на поля таблицы или на расчетные поля. SQL также предоставляет нам возможность использовать псевдонимы вместо имен таблиц. Это дает нам такие преимущества, как более короткий синтаксис SQL и позволяет многократно использовать одну и ту же таблицу в операторе SELECT.

Run SQLSELECT Seller_name, SUM(Amount) AS Sum1 
FROM Sellers AS S, Sumproduct AS SP 
WHERE S.City = SP.City 
GROUP BY Seller_name

Мы отразили общую сумму реализуемого товара по каждому продавцу. В нашем SQL запросе мы использовали следующие псевдонимы: для расчетного поля SUM(Amount) псевдоним Sum1, для таблицы Sellers псевдоним S и для Sumproduct псевдоним SP. Заметим, что псевдонимы таблиц могут быть применены также и в других предложениях как ORDER BY, GROUP BY и других.

2. Самосочетание (SELF JOIN)

Рассмотрим пример. Предположим, нам нужно узнать адрес продавцов, торгующих в той же стране, что и John Smith. Для этого создадим следующий запрос:

Run SQLSELECT Address, City, Country, Seller_name
FROM Sellers
WHERE Country = (SELECT Country 
                 FROM Sellers 
                 WHERE Seller_name = 'John Smith')

Также эту задачу мы можем решить и через самосочетание, прописав следующий код:

Run SQLSELECT S1.Address, S1.City, S1.Country, S1.Seller_name
FROM Sellers AS S1, Sellers AS S2 
WHERE S1.Country = S2.Country AND S2.Seller_name = 'John Smith'

Для решения этой задачи использовались псевдонимы. Первый раз для таблицы Sellers присвоили псевдоним S1, второй раз – псевдоним S2. После этого эти псевдонимы можно использовать в качестве имен таблиц. В операторе WHERE мы к названию каждого поля добавляем префикс S1, для того чтобы СУБД понимающая поля какой таблицы нужно выводить (поскольку мы из одной таблицы сделали две виртуальные). Предложение WHERE сначала объединяет таблицы, а затем фильтрует данные второй таблицы по полю Seller_name, чтобы вернуть только необходимые значения.

Самосочетание часто используют для замены подзапросов, выбирающих данные из той же таблицы, что и внешний оператор SELECT. Хотя конечный результат получается тем самым, многие СУБД прорабатывают сочетание гораздо быстрее, чем подзапросы. Следует поэкспериментировать, чтобы определить, какой запрос работает быстрее.

3. Естественное сочетание

Естественное сочетание – это сочетание, в котором вы выбираете только не повторяющиеся столбцы. Обычно это делается с помощью записи (SELECT*) для одной таблицы и указанием перечня полей – для остальных таблиц. К примеру:

Run SQLSELECT SP.*, S.Country
FROM Sumproduct AS SP, Sellers AS S 
WHERE SP.City = S.City

В этом примере метасимвол (*) используется только для первой таблицы. Все остальные столбцы указаны явно, поэтому дубликаты столбцов не выбираются.

4. Внешнее сочетание (OUTER JOIN)

Обычно при объединении связывают строки одной таблицы с соответствующими строками другой, однако в некоторых случаях может потребоваться включать в результат строки, не имеющие связанных строк в другой таблице (т.е. выбираются все строки из одной таблицы и добавляются только связаны строки из другой). Сочетание такого типа называется внешним. Для этого используются ключевые слова OUTER JOIN...ON... с приставкой LEFT или RIGHT.

Рассмотрим пример, предварительно добавив в таблицу Sellers нового продавца – Semuel Piter, который еще нет продаж:

Run SQLSELECT Seller_name, SUM(Quantity) AS Qty
FROM Sellers2 
LEFT OUTER JOIN Sumproduct 
ON Sellers2.City = Sumproduct.City
GROUP BY Seller_name

Данным запросом мы извлекли список всех продавцов в базе и подсчитали для них общее количество проданного товара за все месяцы. Видим, что по новому продавцу Semuel Piter отсутствуют продажи. Если бы мы использовали внутреннее сочетание, то нового продавца мы бы не увидели, поскольку у него нет записей в таблице Sumproduct. Мы также можем изменять направление сочетания не только прописывая LEFT или RIGHT, но и просто изменяя порядок таблиц (то есть такие две записи будут давать одинаковый результат: Sellers LEFT OUTER JOIN Sumproduct и Sum JOIN Sellers).

Также некоторые СУБД позволяют осуществлять внешнее сочетание по упрощенной записи, используя знаки *= и =*, что соответствует LEFT OUTER JOIN и RIGHT OUTER JOIN соответственно. Таким образом, предварительный запрос можно было бы переписать так:

SELECT Seller_name, SUM(Quantity) AS Qty
FROM Sellers, Sumproduct
WHERE Sellers.City *= Sumproduct.City

К сожалению, MS Access не поддерживает сокращенную запись для внешнего сочетания.

5. Полное внешнее сочетание (FULL OUTER JOIN)

Также существует и другой тип внешнего сочетания – полное внешнее сочетание, отображающее все строки из обеих таблиц и связывающее только те, которые могут быть связаны. Синтаксис полного внешнего сочетания:

SELECT Seller_name, Product
FROM Sellers 
FULL OUTER JOIN Sumproduct 
ON Sellers.City = Sumproduct.City

Опять же, полное внешнее соединение не поддерживают следующие СУБД: MS Access, MySQL, SQL Server и Sybase. Как обойти эту несправедливость, мы рассмотрим в следующей главе.