Увы редко получается писать, но после среды скорее всего в плотную вернуть к блогу.
Сегодня поговорим о JOIN. Согласно Wiki:
JOIN — оператор языка SQL, который является реализацией операции соединения реляционной алгебры. Входит в раздел FROM операторов SELECT, UPDATE или DELETE.
Операция соединения, как и другие бинарные операции, предназначена для обеспечения выборки данных из двух таблиц и включения этих данных в один результирующий набор. Отличительной особенностью операции соединения является следующее:
-
в схему таблицы-результата входят столбцы обеих исходных таблиц (таблиц-операндов), то есть схема результата является «сцеплением» схем операндов;
-
каждая строка таблицы-результата является «сцеплением» строки из одной таблицы-операнда со строкой второй таблицы-операнда.
Большинство начинающих разработчиков используют CROSS JOIN сами того не подозревая что создает при большом объеме выборки не рентабельные затраты на использование системы БД.
Для примера будем использовать 2 примитивные таблицы
T1 | T2 | |||
k1 | d1 | k1 | d2 | |
1 | 1 | 1 | 10 | |
2 | 2 | 2 | 20 | |
3 | 3 | 5 | 50 | |
4 | 4 | 6 | 60 |
содержание
CROSS JOIN
и напишем «классический» SELECT
1 2 3 |
SELECT d1, d2 FROM T1, T2 WHERE k1 = k2 |
Результат(где k1 = k2):
1:10
2:20
Вроде все ок со стороны пользователя, что просили то и получили. А теперь заглянем под «копот».
На самом деле выполняется сначала первая часть выражения:
1 2 |
SELECT d1, d2 FROM T1, T2 |
и результат выполнения за ширмой будет следующим
1 | 10 |
1 | 20 |
1 | 50 |
1 | 60 |
1 | 10 |
1 | 20 |
1 | 50 |
1 | 60 |
2 | 10 |
2 | 20 |
2 | 50 |
2 | 60 |
2 | 10 |
2 | 20 |
2 | 50 |
2 | 60 |
На первый взгляд ничего критичного, но если у нас пару миллионов значений в каждой таблице?
В результате будет 4 биллиона значений в которых WHERE начнет фильтровать. В нашем случае из 16 остается только 2
Избегается CROSS JION с помощью нормальных выражений.
INNER JOIN
Оператор внутреннего соединения INNER JOIN соединяет две таблицы. Порядок таблиц для оператора неважен, поскольку оператор является симметричным.
1 2 3 4 |
SELECT d1,d2 FROM T1 INNER JOIN T2 ON T1.k1=T2.k2 |
Результат:
d1 | d2 |
1 | 10 |
2 | 20 |
LEFT JOIN
LEFT JOIN говорит взять из левой таблицы все значения. Мы подключаем к левой таблицы все где совпадают значения
1 2 3 4 |
SELECT d1,d2 FROM T1 LEFT JOIN T2 ON T1.k1=T2.k2 |
Результат:
d1 | d2 |
1 | 10 |
2 | 20 |
3 | Null |
4 | Null |
RIGHT JOIN
RIGHT JOIN противоположен LEFT.
Так как мы работаем от правой таблицы , а в ней не существует ключа 3 и 4 то в результате мы увидим 50 и 60 справа так как правая таблица делает полную выборку. А слева будет Null так как ключа 5 и 6 нет в таблице 1
1 2 3 4 |
SELECT d1,d2 FROM T1 RIGHT JOIN T2 ON T1.k1=T2.k2 |
Результат:
d1 | d2 |
1 | 10 |
2 | 20 |
Null | 50 |
Null | 60 |
FULL JOIN (не все БД поддерживают)
FULL JOIN сливает таблицу где ключи равны либо отсутствуют в одной из ьаблиц.
Так как мы работаем от правой таблицы , а в ней не существует ключа 3 и 4 то в результате мы увидим 50 и 60 справа так как правая таблица делает полную выборку. А слева будет Null так как ключа 5 и 6 нет в таблице 1
1 2 3 4 |
SELECT d1,d2 FROM T1 FULL JOIN T2 ON T1.k1=T2.k2 |
Результат:
d1 | d2 |
1 | 10 |
2 | 20 |
3 | Null |
4 | Null |
Null | 50 |
Null | 60 |
Так как поддерживается FULL Join не всеми базами данных есть альтернативное решение через UNION
UNION
UNION не имеет ничего общего с JOIN. UNION означает продолжить данные. То есть взять таблицу 1 и после нее продолжить таблицу 2
1 2 3 4 5 6 7 8 9 10 |
SELECT d1,d2 FROM T1 LEFT JOIN T2 ON T1.k1=T2.k2 UNION ALL SELECT d1,d2 FROM T1 RIGHT JOIN T2 ON T1.k1=T2.k2 WHERE d1 is Null |
Результат:
d1 | d2 |
1 | 10 |
2 | 20 |
3 | Null |
4 | Null |
Null | 50 |
Null | 60 |
Стоит обратить внимания на
1 |
WHERE d1 is Null |
в разных базах своя проверка на Null будьте внимательней.
У кого все еще остались вопросы, рекомендую к просмотру видео Vladimira Mozhenkova