К статьям

Объединения

5 мин


Объединение таблиц в запросе

Часто при написании запросов возникает необходимость объединить две таблицы или набора данных. Ключевое отличие объединений от соединения заключается в том, что при соединении к одному набору данных присоединяется второй справа или слева с возможностью указать условия такого соединения, а при объединении один набор данных присоединяется ко второму снизу без возможности фильтрации. 

Если брать за пример самый простой случай, то:
1) Соединения чаще всего делаются для добавления в результат дополнительных полей, которых нет в одной таблице, но они есть в другой.
2) Объединения чаще всего используются для добавления в результат дополнительных строк, которые так же отсутствуют в одной таблице, но есть в другой.

На практике оба этих механизма могут использоваться и для одного и для другого, но для простоты понимания, наверное, это самое подходящее объяснение.

Если изобразить это отличие визуально, то нужно задать два исходных набора данных:

Представим, что у нас есть таблица Фрукты:

Название Цвет Количество
Банан Желтый 2
Апельсин Оранжевый 5
Яблоко Зеленый 3

И таблица Овощи:

Название Цвет Количество
Огурец Зеленый 4
Тыква Оранжевый 2
Кукуруза Желтый 5

Если бы мы захотели узнать какие у нас есть фрукты и овощи одинакового цвета, то мы бы использовали соединение:

 ВЫБРАТЬ 

    Фрукты.Название КАК НазваниеФрукта,

    Фрукты.Цвет КАК ЦветФрукта,

    Овощи.Название КАК НазваниеОвоща,

    Овощи.Цвет КАК ЦветОвоща

Из Фрукты КАК Фрукты

    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Овощи КАК Овощи

    ПО Фрукты.Цвет = Овощи.Цвет 

В результате, используя внутреннее соединение, получили бы таблицу, содержащую только фрукты и овощи одинакового цвета:

НазваниеФрукта ЦветФрукта НазваниеОвоща ЦветОвоща
Банан Желтый Кукуруза Желтый
Апельсин Оранжевый Тыква Оранжевый
Яблоко Зеленый Огурец Зеленый

А в ситуации когда нам захотелось бы получить данные по всем фруктам и овощам в одном наборе данных, нам бы пригодилось объединение.

 ВЫБРАТЬ

    Фрукты.Название КАК Название,

    Фрукты.Цвет КАК Цвет,

    Фрукты.Количество КАК Количество

ИЗ

    Фрукты КАК Фрукты

 

ОБЪЕДИНИТЬ ВСЕ

 

ВЫБРАТЬ

    Овощи.Название,

    Овощи.Цвет,

    Овощи.Количество

ИЗ

    Овощи КАК Овощи

В результате мы получим объединенную таблицу содержащую данные из обеих таблиц

Название Цвет Количество
Яблоко Зеленый 3
Апельсин Оранжевый 5
Банан Желтый 2
Огурец Зеленый 4
Тыква Оранжевый 2
Кукуруза Желтый 5

Как видите, данные таблицы Овощи присоединились к данным таблицы Фрукты снизу.

При  использовании соединений стоит учитывать, что СУБД сама не может определить какие данные в каких столбцах находятся и как их необходимо сопоставлять, потому стоит следить за соответствием полей из разных таблиц самостоятельно. Порядок полей в запросе и определяет их соответствие. В этом примере важно, чтобы поля Название, Цвет, Количество располагались в выборке из обеих таблиц именно в таком порядке, иначе мы получим совсем не то, что хотели.

Например, я поменяю местами цвет и количество в выборке из таблицы Овощи таким образом, чтобы их порядок не совпадал с порядком полей в выборке из таблицы Фрукты:

 ВЫБРАТЬ

    Фрукты.Название КАК Название,

    Фрукты.Цвет КАК Цвет,

    Фрукты.Количество КАК Количество

ИЗ

    Фрукты КАК Фрукты

 

 ОБЪЕДИНИТЬ ВСЕ

 

ВЫБРАТЬ

    Овощи.Цвет,

    Овощи.Название,

    Овощи.Количество

ИЗ

    Овощи КАК Овощи

В этом случае мы получим следующий результат:

Название Цвет Количество
Яблоко Зеленый 3
Апельсин Оранжевый 5
Банан Желтый 2
Зеленый Огурец 4
Оранжевый Тыква 2
Желтый Кукуруза 5

Из-за того, что мы поменяли поля местами, то и результат получили соответствующий. Поле Цвет из таблицы Овощи попало в колонку Название, и испортило результат. Исходя из этого можно сделать вывод, названия полей в результирующей таблице определяются по первой таблице в объединении. Это важный момент, соответствие полей всегда нужно контролировать вручную. 

Так же, в случае если нам необходимо объединить наборы данных которые отличаются по количеству полей, например в таблице Фрукты было бы два поля Название и Цвет, а в таблице Овощи так же остались бы все поля Название, Цвет и Количество, то такое объединение тоже можно выполнить, нам только нужно будет установить какое-то значение по умолчанию для недостающего поля. Больше подходящее по ситуации, например "Не заполнено", 0, Null и т.д. 

 ВЫБРАТЬ

    Фрукты.Название КАК Название,

    Фрукты.Цвет КАК Цвет,

    "Не заполнено" КАК Количество

ИЗ

    Фрукты КАК Фрукты

 

ОБЪЕДИНИТЬ ВСЕ

 

ВЫБРАТЬ

    Овощи.Цвет,

    Овощи.Название,

    Овощи.Количество

ИЗ

    Овощи КАК Овощи  

В результате мы получим:

Название Цвет Количество
Яблоко Зеленый Не заполнено
Апельсин Оранжевый Не заполнено
Банан Желтый Не заполнено
Зеленый Огурец 4
Оранжевый Тыква 2
Желтый Кукуруза 5

Используя такую технику можно в целом обходить практически все ситуации когда какого-то поля нехватает.

Теперь перейдем к более подробному описанию вариантов синтаксиса объединений. Их бывает два Объединить и Объединить ВСЕ.

Объединить

Используется в тех случаях, когда объединяемые наборы данных могут содержать одинаковые строки, в случае появления дублирующихся строк они будут удалены из результата таким образом, чтобы все строки в результате стали уникальными, то-есть не имели повторений по всем полям.

Объединить ВСЕ

Используется в тех случаях, когда нам неважно будут ли наборы содержать не уникальные строки, объединение произойдет полностью, без дополнительной обработки результата. Если попадутся полностью одинаковые строки, то они так и останутся в результате. 

Следует учитывать, какие именно данные будут содержаться во всех объединяемых наборах данных, и стараться использовать Объединить ВСЕ в случаях, когда нам точно известно, что наборы не будут иметь дублирующихся строк. При использовании Объединить, операция поиска и удаления дублей строк выполняется всегда, даже если в итоге это никак не повлияет на результат, но какое-то время эта операция занимает, и тратит вычислительные ресурсы впустую, что может замедлить выполнение вашего запроса без какого либо полезного эффекта.

Задачи на эту тему: