Соединение таблиц или действие оператора SQL JOIN на примерах

Рубрика: SQL
27 декабря 2016

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

Синтаксис соединения таблиц оператором JOIN имеет вид:

FROM <таблица 1>
 [INNER]
 {{LEFT | RIGHT | FULL } [OUTER]} JOIN <таблица 2>
[ON <предикат>]

Предикат в этой конструкции определяет условие соединения строк из разных таблиц.

Допустим есть две таблицы (Auto слева и Selling справа), в каждой по четыре записи. Одна таблица содержит названия марок автомобилей (Auto), вторая количество проданных автомобилей (Selling):

id   name          id   sum
--   ----          --   ----
1    bmw           1    250
2    opel          5    450
3    kia           3    300
4    audi          6    400

Далее соединим эти таблицы по полю id несколькими различными способами. Совпадающие значения выделены красным для лучшего восприятия.

1. Внутреннее соединение (INNER JOIN) означает, что в результирующий набор попадут только те соединения строк двух таблиц, для которых значение предиката равно TRUE. Обычно используется для объединения записей, которые есть и в первой и во второй таблице, т. е. получения пересечения таблиц:

Красным выделена область, которую мы должны получить.

Итак, сам запрос:

SELECT * FROM 'Auto'
INNER JOIN 'Selling' ON 'Auto'.id = 'Selling'.id

И результат:

id   name          id   sum
--   ----          --   ----
1    bmw           1    250
3    kia           3    300

Ключевое слово INNER в запросе можно опустить.

В итоге запрос отбирает и соединяет те записи, у которых значение поля id в обоих таблицах совпадает.

2. Внешнее соединение (OUTER JOIN) бывает нескольких видов. Первым рассмотрим полное внешнее объединение (FULL OUTER JOIN), которое объединяет записи из обоих таблиц (если условие объединения равно true) и дополняет их всеми записями из обоих таблиц, которые не имеют совпадений. Для записей, которые не имеют совпадений из другой таблицы, недостающее поле будет иметь значение NULL. Граф выборки записей будет иметь вид:

Переходим к запросу:

SELECT * FROM 'Auto'
FULL OUTER JOIN 'Selling' ON 'Auto'.id = 'Selling'.id

Результат:

id   name          id   sum
--   ----          --   ----
1    bmw           1    250
2    opel        NULL   NULL
3    kia           3    300
4    audi        NULL   NULL
NULL NULL          5    450
NULL NULL          6    400

То есть мы получили все записи, которые есть в обоих таблицах. Записи у которых значение поля id совпадает соединяются, а у записей для которых совпадений не найдено недостающие поля заполняются значением NULL.

Ключевое слово OUTER можно опустить.

3. Левое внешнее объединение (LEFT OUTER JOIN). В этом случае получаем все записи удовлетворяющие условию объединения, плюс все оставшиеся записи из внешней таблицы, которые не удовлетворяют условию объединения. Граф выборки:

Запрос:

SELECT * FROM 'Auto'
LEFT OUTER JOIN 'Selling' ON 'Auto'.id = 'Selling'.id

Результат:

id   name          id   sum
--   ----          --   ----
1    bmw           1    250
2    opel        NULL   NULL
3    kia           3    300
4    audi        NULL   NULL

Запрос также можно писать без ключевого слова OUTER.

В итоге здесь мы получили все записи таблицы Auto. Записи для которых были найдены совпадения по полю id в таблице Selling соединяются, для остальных недостающие поля заполняются значением NULL.

Еще существует правое внешнее объединение (RIGHT OUTER JOIN). Оно работает точно также как и левое объединение, только  в качестве внешней таблицы будет использоваться правая (в нашем случае таблица Selling или таблица Б на графе).

Далее рассмотрим остальные возможные выборки с использованием объединения двух таблиц.

4. Получить все записи из таблицы А, которые не имеют объединения из таблицы Б. Граф:

То есть в нашем случае, нам надо получить все автомобили из таблицы Auto, которые не имеют продаж в таблице Selling.

Запрос:

SELECT * FROM 'Auto'
LEFT OUTER JOIN 'Selling' ON 'Auto'.id = 'Selling'.id
WHERE 'Selling'.id IS null

Результат:

id   name          id   sum
--   ----          --   ----
2    opel        NULL   NULL
4    audi        NULL   NULL

5. И последний вариант, получить все записи из таблицы А и Таблицы Б, которые не имеют объединений. Граф:

В нашем случае мы должны получить все записи из таблицы Auto, которые не связаны с таблицей Selling, и все записи из таблицы Selling, которые не имеют сопоставления из таблицы Auto.

Запрос:

SELECT * FROM 'Auto'
FULL OUTER JOIN 'Selling'
ON 'Auto'.id = 'Selling'.id
WHERE 'Auto'.id IS null
OR 'Selling'.id IS null

Результат:

id   name          id   sum
--   ----          --   ----
2    opel        NULL   NULL
4    audi        NULL   NULL
NULL NULL          5    450
NULL NULL          6    400

На этом все, до новых встреч на страницах блога.

(18 оценок, среднее: 4,83 из 5)
Loading...

Получай статьи почтой:


Комментарии
  1. Александр

    Спасибо за полезную и интересную информацию!

    7 января 2017 16:51
  2. Frost364

    Спрашиваю у программиста на новой работе- почему ты используешь inner join вместо простого сравнения полей , отвечает меня так научили

    19 сентября 2017 22:33
  3. Вадим

    Спасибо! Самое наглядное объяснение соединений.

    20 сентября 2017 15:00
  4. Игорь

    Рисунки странные. Автор похоже теорию множеств не изучал. Множества должны быть одной природы при пересечении и объединении. Таблицы же содержат объекты (записи, кортежи) вообще говоря разной природы, которые могут имеют лишь общие поля, по которым происходит соединение. Слово join переводится как соединение, а не объединение. Объединение в sql также существует: union или union all. В статье какая-то каша, впрочем, судя по комментариям ее мало кто читал.

    31 августа 2018 22:40
  5. Андрей

    Рисунки просто абстрактно показывают, что имеется ввиду, для упрощения восприятия. Если удосужиться и посмотреть запросы и результаты, то все моментально расставляется по своим местам.

    4 апреля 2019 16:48

Оставить комментарий




Subscribe without commenting