При данном типе соединения будет отображаться все, что содержится в таблице invoices. Поскольку Customer 1 не заказывал песни, данная запись не указывается. Однако, как показано на рис. 72, мы объединяем все пять записей из таблицы invoices только с четырьмя записями из таблицы customers. Помните, что в таблице invoices записи для Customer 1 или Customer 5 отсутствуют, а клиенту Customer 2 было выставлено два счета. В отличие от внутреннего соединения, которое отображает равное количество записей из каждой таблицы, в результате использования левого внешнего соединения вернется больше записей из «левой» таблицы. Проанализируем результат данного запроса, чтобы понять работу браузера SQL.
Рис. 72
SQL-запрос для левого внешнего соединения аналогичен запросу, который мы использовали для внутреннего соединения. Отличие только в использовании условия LEFTOUTERJOIN.
SELECT
i. InvoiceId,
c. CustomerId,
c. Name,
c. Address,
i. InvoiceDate,
i. BillingAddress,
i. Total
FROM
invoices AS i
LEFT OUTER JOIN
customers AS c
ON
i. CustomerId = c.CustomerId
Рис. 73
Примечание
Слово «внешнее» (OUTER) необязательно.
Когда мы анализируем результаты, полученные при использовании левого соединения, мы видим, что браузер SQL добавил данные типа Null. Помните, что информация о Customer 6 в таблице customers отсутствует. Добавление данных типа Null показывает, как браузер SQL обрабатывает нашу попытку сопоставить пять записей из таблицы invoices только с четырьмя записями из таблицы customers. Использование левого соединения полезно, так как это позволяет нам видеть несовпадения в наших данных. Мы можем создавать списки клиентов, которым не выставляли счета, или выполнять поиск данных, которые были удалены в правой таблице, но все еще существуют в левой.
Правое внешнее соединение (RIGHT OUTER JOIN)
Внимание
В SQLite не поддерживается использование правого внешнего соединения. Но мы эту тему рассмотрим, поскольку правое внешнее соединение по-прежнему популярно в других реализациях РСУБД. Позже мы рассмотрим обходной путь для применения правых соединений в SQLite.
В результате использования правого внешнего соединения RIGHT OUTER JOIN возвращаются все данные из правой таблицы, а также соответствующая информация из левой таблицы. Правое соединение — зеркальное отображение левого соединения.
Рис. 74
При использовании правого соединения берутся все поля из правой таблицы (customers) и ее данные сопоставляются с любыми соответствующими данными из таблицы invoices. Поскольку Customer 6 в таблице customers отсутствует, эта запись игнорируется.
Рис. 75
Оператор SQL, необходимый для создания правого соединения, такой же, как и в двух других соединениях, которые мы рассмотрели ранее.
Примечание
Ключевое слово «внешнее» (OUTER) необязательно. Вариант RIGHT JOIN дает тот же результат.
SELECT
i. InvoiceId,
c. CustomerId,
c. Name,
c. Address,
i. InvoiceDate,
i. BillingAddress,
i. Total
FROM
invoices AS i
RIGHT OUTER JOIN
customers AS c
ON
i. CustomerId = c.CustomerId
Рис. 76
В результате использования данного соединения вернулось наибольшее количество записей из трех изученных ранее соединений. Записей Customer 1 и Customer 5 нет в таблице invoices, поэтому им присвоены значения Null. Две записи из таблицы invoices относятся к Customer 2, поэтому в результате объединения данные Customer 2 были указаны дважды.
Правые соединения используются реже, чем левые. Поскольку SQLite не распознает правое соединение, в запросе рекомендуется изменить порядок таблиц, что приведет к тому же набору результатов. Эту тему мы рассмотрим позже в этой главе.
Внутренние соединения для случаев соединения двух и более таблиц
Можно соединять и более двух таблиц. Чтобы добавить дополнительные таблицы, нужно просто следовать тем же правилам, что мы рассмотрели ранее, когда рассказывали про внутренние соединения. Рассмотрим схему базы данных на рис. 77. Мы видим, что помимо связи между таблицами invoices и customers существует также связь между полем SupportRepId из таблицы customers и полем EmployeeId из таблицы employees.
Рис. 77