Кроме того LEFT JOIN, как RIGHT JOINи FULL JOINвписаться?
Кроме того LEFT JOIN, как RIGHT JOINи FULL JOINвписаться?
Ответы:
Предполагается, что вы объединяете столбцы без дубликатов, что является очень распространенным случаем:
Внутреннее соединение A и B дает результат пересечения A B, то есть внутреннюю часть пересечения диаграммы Венна .
Внешнее объединение A и B дает результаты объединения B, то есть внешние части объединения диаграммы Венна.
Примеры
Предположим, у вас есть две таблицы с одним столбцом и данными следующим образом:
A B
- -
1 3
2 4
3 5
4 6
Обратите внимание, что (1,2) являются уникальными для A, (3,4) являются общими, и (5,6) являются уникальными для B.
Внутреннее соединение
Внутреннее соединение, использующее любой из эквивалентных запросов, дает пересечение двух таблиц, то есть двух общих строк, которые они имеют.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
Левое внешнее соединение
Левое внешнее соединение даст все строки в A плюс все общие строки в B.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
Правое внешнее соединение
Правое внешнее соединение даст все строки в B плюс все общие строки в A.
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
Полное внешнее соединение
Полное внешнее объединение даст вам объединение A и B, то есть всех строк в A и всех строк в B. Если что-то в A не имеет соответствующих данных в B, то часть B пуста, и порок наоборот.
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
Диаграммы Венна на самом деле не делают это для меня.
Например, они не показывают какого-либо различия между перекрестным соединением и внутренним соединением или, в более общем случае, показывают какое-либо различие между различными типами предикатов объединения или предоставляют основу для рассуждений о том, как они будут работать.
Ничто не заменит понимание логической обработки, и в любом случае это относительно просто понять.
onпредложение по всем строкам, начиная с шага 1, сохраняя те, в которых предикат оценивается какtrue(Примечание: на практике оптимизатор запросов может найти более эффективные способы выполнения запроса, чем приведенное выше чисто логическое описание, но конечный результат должен быть таким же)
Я начну с анимированной версии полного внешнего соединения . Дальнейшее объяснение следует.
Исходные таблицы

Сначала начните с CROSS JOIN(AKA декартово произведение). Это не имеет ONпредложения и просто возвращает каждую комбинацию строк из двух таблиц.
ВЫБЕРИТЕ А.ЦВЕТ, Б.ЦВЕТ ИЗ КРЕСТА СОЕДИНИТЕ B

Внутренние и внешние соединения имеют предикат предложения ON.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour
Выше классическое равное соединение.

Условие внутреннего соединения не обязательно должно быть условием равенства и не должно ссылаться на столбцы обеих (или даже обеих) таблиц. Оценка A.Colour NOT IN ('Green','Blue')по каждому ряду результатов перекрестного соединения.

ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B ON 1 = 1
Условие соединения оценивается как true для всех строк в результате перекрестного соединения, так что это то же самое, что и перекрестное соединение. Я не буду повторять картину из 16 рядов снова.
Внешние объединения логически оцениваются так же, как и внутренние соединения, за исключением того, что если строка из левой таблицы (для левого объединения) вообще не объединяется ни с одной строкой из правой таблицы, она сохраняется в результате со NULLзначениями для правые колонны.

Это просто ограничивает предыдущий результат, возвращая только те строки, где B.Colour IS NULL. В этом конкретном случае это будут строки, которые были сохранены, так как они не совпадали в правой таблице, и запрос возвращает одну красную строку, не совпадающую в таблице B. Это известно как анти-полусоединение.
Важно выбрать столбец для IS NULLтеста, который не имеет значения NULL или для которого условие соединения гарантирует, что любые NULLзначения будут исключены, чтобы этот шаблон работал правильно, и избегал просто возвращать строки, которые, как оказалось, имеют NULLзначение для этого столбец в дополнение к несогласованным строкам.

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

Полные внешние объединения объединяют поведение левого и правого объединений и сохраняют несовпадающие строки из левой и правой таблиц.

Строки в перекрестном соединении не соответствуют 1=0предикату. Все строки с обеих сторон сохраняются с использованием обычных правил внешнего соединения с NULL в столбцах таблицы на другой стороне.

С незначительной поправкой к предыдущему запросу можно смоделировать одну UNION ALLиз двух таблиц.

Обратите внимание, что WHEREпредложение (если оно присутствует) логически выполняется после объединения. Одной из распространенных ошибок является выполнение левого внешнего соединения, а затем включение предложения WHERE с условием в правой таблице, которое заканчивается исключением несовпадающих строк. Вышеуказанное завершает выполнение внешнего соединения ...

... А затем выполняется предложение "Где". NULL= 'Green'не оценивается как истина, поэтому строка, сохраненная внешним соединением, в конечном итоге отбрасывается (вместе с синим), эффективно преобразовывая соединение обратно во внутреннее.
Если бы целью было включить только строки из B, где Color - зеленый, и все строки из A независимо от правильного синтаксиса были бы

Посмотрите эти примеры в прямом эфире на SQLFiddle.com .
Объединения используются для объединения данных из двух таблиц, в результате чего получается новая временная таблица. Объединения выполняются на основе того, что называется предикатом, в котором указывается условие, используемое для выполнения объединения. Разница между внутренним соединением и внешним соединением заключается в том, что внутреннее объединение будет возвращать только те строки, которые действительно совпадают, основываясь на предикате соединения. Например, давайте рассмотрим таблицу Employee and Location:

Внутреннее объединение : - Внутреннее объединение создает новую таблицу результатов, комбинируя значения столбцов двух таблиц ( Employee и Location ) на основе предиката объединения. Запрос сравнивает каждую строку Employee с каждой строкой Location, чтобы найти все пары строк, которые удовлетворяют предикату соединения. Когда предикат соединения удовлетворяется путем сопоставления значений, отличных от NULL, значения столбцов для каждой соответствующей пары строк Employee и Location объединяются в результирующую строку. Вот как будет выглядеть SQL для внутреннего объединения:
select * from employee inner join location on employee.empID = location.empID
OR
select * from employee, location where employee.empID = location.empID
Теперь вот как будет выглядеть результат выполнения SQL:

Внешнее соединение: - Для внешнего соединения не требуется, чтобы каждая запись в двух соединенных таблицах имела соответствующую запись. Объединенная таблица сохраняет каждую запись, даже если другой соответствующей записи не существует. Внешние объединения подразделяются далее на левые внешние и правые внешние объединения, в зависимости от того, какие строки таблицы сохраняются (левые или правые).
Левое внешнее соединение: - результат левого внешнего соединения (или просто левого соединения) для таблиц Employee и Location всегда содержит все записи «левой» таблицы ( Employee ), даже если условие соединения не находит подходящую запись в «Правильный» стол ( Location ). Вот как будет выглядеть SQL для левого внешнего соединения, используя таблицы выше:
select * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Теперь вот как будет выглядеть результат выполнения этого SQL:

Правое внешнее соединение : - Правое внешнее соединение (или правое соединение) очень похоже на левое внешнее соединение, за исключением обработки обращенных таблиц. Каждая строка из «правой» таблицы ( Location ) появится в объединенной таблице хотя бы один раз. Если соответствующая строка из «левой» таблицы ( Employee ) не существует, в столбцах Employee появится NULLдля тех записей, которые не совпадают в Location . Вот как выглядит SQL:
select * from employee right outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Используя таблицы выше, мы можем показать, как будет выглядеть результирующий набор правого внешнего соединения:

Полные внешние соединения: - внешнее объединение: - Полное внешнее объединение или полное объединение - для сохранения несоответствующей информации путем включения несовпадающих строк в результаты объединения, используйте полное внешнее объединение. Он включает все строки из обеих таблиц, независимо от того, имеет ли другая таблица совпадающее значение.
Извлекать только совпадающие строки, то есть A intersect B.

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Выберите все записи из первой таблицы и все записи во второй таблице, которые соответствуют соединенным ключам.

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Выберите все записи из второй таблицы и все записи в первой таблице, которые соответствуют соединенным ключам.

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Простыми словами:
Внутреннее соединение извлекать только совпавшие строки.
Принимая во внимание, что внешнее соединение извлекает сопоставленные строки из одной таблицы и все строки в другой таблице .... результат зависит от того, какую из них вы используете:
Слева : соответствующие строки в правой таблице и все строки в левой таблице
Справа : соответствующие строки в левой таблице и все строки в правой таблице или
Полный : все строки во всех таблицах. Неважно, есть ли совпадение или нет
Внутреннее объединение показывает только строки, если на другой (правой) стороне объединения имеется соответствующая запись.
На (левом) внешнем соединении отображаются строки для каждой записи с левой стороны, даже если на другой (правой) стороне объединения нет совпадающих строк. Если соответствующей строки нет, столбцы для другой (правой) стороны будут показывать NULL.
Внутренние объединения требуют, чтобы в объединенной таблице существовала запись со связанным идентификатором.
Внешние объединения возвращают записи для левой стороны, даже если для правой стороны ничего не существует.
Например, у вас есть таблица Orders и OrderDetails. Они связаны "OrderID".
заказы
Информация для заказа
Запрос
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
будет возвращать только заказы, которые также имеют что-то в таблице OrderDetails.
Если вы измените его на OUTER LEFT JOIN
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
LEFT JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
тогда он вернет записи из таблицы Orders, даже если у них нет записей OrderDetails.
Вы можете использовать это, чтобы найти Заказы, у которых нет OrderDetails, указывающего возможный потерянный заказ, добавив предложение where как WHERE OrderDetails.OrderID IS NULL.
SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASCв SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC(MySQL) с успехом. Я не был уверен насчет дополнительных условий, они хорошо сочетаются ...
Простыми словами:
Внутреннее соединение -> Возьмите ТОЛЬКО общие записи из родительской и дочерней таблиц, ГДЕ первичный ключ родительской таблицы соответствует внешнему ключу в дочерней таблице.
Осталось присоединиться ->
псевдокод
1.Take All records from left Table
2.for(each record in right table,) {
if(Records from left & right table matching on primary & foreign key){
use their values as it is as result of join at the right side for 2nd table.
} else {
put value NULL values in that particular record as result of join at the right side for 2nd table.
}
}
Правое соединение : Точно противоположное левому соединению. Поместите имя таблицы в LEFT JOIN справа от правого соединения, вы получите тот же вывод, что и в LEFT JOIN.
Внешнее соединение : Показать все записи в обеих таблицахNo matter what . Если записи в левой таблице не соответствуют правой таблице, основанной на первичном ключе, ключе Forieign, используйте значение NULL в качестве результата объединения.
Пример :

Предположим теперь для 2 таблиц
1.employees , 2.phone_numbers_employees
employees : id , name
phone_numbers_employees : id , phone_num , emp_id
Здесь таблица employee является главной таблицей, phone_numbers_employees является дочерней таблицей (она содержит emp_idвнешний ключ, который соединяет employee.idее с дочерней таблицей.)
Внутренние соединения
Принимайте записи только из 2 таблиц, ЕСЛИ если первичный ключ таблицы сотрудников (его идентификатор) совпадает с внешним ключом дочерней таблицы phone_numbers_employees (emp_id) .
Таким образом, запрос будет:
SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Здесь берутся только совпадающие строки в первичном ключе = внешний ключ, как описано выше. Здесь несоответствующие строки в первичном ключе = внешний ключ пропускаются в результате объединения.
Левый присоединяется :
При левом соединении сохраняются все строки левой таблицы, независимо от того, есть ли строка, соответствующая правой таблице.
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Внешние соединения :
SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Схематически это выглядит так:

Вы используете INNER JOINдля возврата всех строк из обеих таблиц, где есть совпадение. т.е. в результирующей таблице все строки и столбцы будут иметь значения.
В OUTER JOINрезультирующей таблице могут быть пустые столбцы. Внешнее соединение может быть или LEFTили RIGHT.
LEFT OUTER JOIN возвращает все строки из первой таблицы, даже если во второй таблице нет совпадений.
RIGHT OUTER JOIN возвращает все строки из второй таблицы, даже если в первой таблице нет совпадений.
Это хорошее схематичное объяснение для всех видов соединений
источник: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOINтребует, чтобы при сравнении двух таблиц было как минимум совпадение. Например, таблица A и таблица B, которые подразумевают A ٨ B (пересечение A B).
LEFT OUTER JOIN а также LEFT JOIN такие же. Это дает все записи, совпадающие в обеих таблицах и все возможности левой таблицы.
Аналогично RIGHT OUTER JOINи RIGHT JOINодинаковы. Это дает все записи, совпадающие в обеих таблицах и все возможности правой таблицы.
FULL JOINэто комбинация LEFT OUTER JOINи RIGHT OUTER JOINбез дублирования.
Ответ заключается в значении каждого, так и в результатах.
Примечание:
ВSQLiteне существуетRIGHT OUTER JOINилиFULL OUTER JOIN.
А также вMySQLнетFULL OUTER JOIN.
Мой ответ основан на примечании выше .
Когда у вас есть две таблицы, подобные этим:
--[table1] --[table2]
id | name id | name
---+------- ---+-------
1 | a1 1 | a2
2 | b1 3 | b2
CROSS JOIN / OUTER JOIN:
Вы можете иметь все данные этих таблиц с CROSS JOINили просто ,так:
SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
1 | a1 | 3 | b2
2 | b1 | 1 | a2
2 | b1 | 3 | b2
ВНУТРЕННЕЕ СОЕДИНЕНИЕ:
если вы хотите добавить фильтр к вышеуказанным результатам на основе отношения, которое table1.id = table2.idвы можете использовать INNER JOIN:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
LEFT [OUTER] JOIN:
Если вы хотите, чтобы все строки одной из таблиц в приведенном выше результате - с одинаковым отношением - вы можете использовать LEFT JOIN:
(Для RIGHT JOIN просто измените место таблиц)
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
FULL OUTER JOIN:
Если вы также хотите, чтобы в ваших результатах были все строки другой таблицы, вы можете использовать FULL OUTER JOIN:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
--[Results:]
id | name | id | name
-----+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
Null | Null | 3 | b2
Ну, так как вам нужно, вы выбираете каждый, который покрывает ваши потребности;).
full outer joinв MySQL ее тоже нет.
Внутреннее соединение.
Объединение объединяет строки из двух таблиц. Внутреннее объединение попыток , чтобы обеспечить соответствие двух таблиц на основе указанных критериев в запросе, и возвращает только те строки , которые совпадают. Если строка из первой таблицы в соединении совпадает с двумя строками во второй таблице, то в результатах будут возвращены две строки. Если в первой таблице есть строка, которая не соответствует строке во второй таблице, она не возвращается; аналогично, если во второй таблице есть строка, которая не соответствует строке в первой, она не возвращается.
Внешнее Присоединение.
Влево присоединиться попытками найти совпасть строки из первой таблицы , в строки во второй таблице. Если он не может найти совпадение, он вернет столбцы из первой таблицы и оставит столбцы из второй таблицы пустыми (пустыми).
INNER JOINнаиболее типичное объединение для двух или более таблиц. Возвращает совпадение данных как для таблицы ON primarykey, так и для отношения forignkey.OUTER JOINтак же, как INNER JOIN, но он также включает в себя NULLданные на ResultSet.
LEFT JOIN= INNER JOIN+ Несоответствующие данные левой таблицы с Nullсовпадением на правой таблице.RIGHT JOIN= INNER JOIN+ Несоответствующие данные правой таблицы с Nullсовпадением на левой таблице.FULL JOIN= INNER JOIN+ Несоответствующие данные в правой и левой таблицах с Nullсовпадениями.INNER JOINи OUTER JOINмы можем написать запросы на самостоятельное соединение.Например:
SELECT *
FROM tablea a
INNER JOIN tableb b
ON a.primary_key = b.foreign_key
INNER JOIN tablec c
ON b.primary_key = c.foreign_key
Я не вижу подробностей о производительности и оптимизаторе в других ответах.
Иногда полезно знать, что только INNER JOIN ассоциативно, что означает, что оптимизатор имеет больше возможностей для игры с ним. Он может изменить порядок соединения, чтобы сделать его быстрее, сохраняя тот же результат. Оптимизатор может использовать большинство режимов соединения.
Как правило, рекомендуется использовать INNER JOINвместо разных видов соединений. (Конечно, если это возможно, учитывая ожидаемый набор результатов.)
Здесь есть несколько хороших примеров и объяснений об этом странном ассоциативном поведении:
INNER JOINэто медленнее, чем LEFT JOINв большинстве случаев, и люди могут использовать LEFT JOINвместо INNER JOINдобавления WHEREдля удаления неожиданных NULLрезультатов;).
INNERмедленнее?
Покритиковав столь любимую диаграмму Венна в красных тонах, я подумал, что будет справедливо опубликовать мою собственную попытку.
Несмотря на то, что ответ @Martin Smith является лучшим из этой группы, он показывает только ключевые столбцы из каждой таблицы, в то время как я считаю, что в идеале также должны быть показаны неключевые столбцы.
Лучшее, что я мог бы сделать за полчаса, я все еще не думаю, что это адекватно показывает, что нулевые значения присутствуют из-за отсутствия значений ключей TableBили что OUTER JOINэто фактически объединение, а не соединение:
TableA a LEFT OUTER JOIN TableB bнаTableB B RIGHT OUTER JOIN TableA a
Точный алгоритм для INNER JOIN, LEFT/RIGHT OUTER JOINявляются следующие:
a(a, b[i])ON ...предложение по каждой паре:ON( a, b[i] ) = true/false?
true, вернуть эту объединенную строку (a, b[i]).Outer Joinвозвращает (виртуальную) пару, используя Nullдля всех столбцов другой таблицы: (a, Null)для внешнего соединения LEFT или (Null, b)для внешнего соединения RIGHT. Это должно гарантировать, что все строки первой таблицы существуют в окончательных результатах.Примечание: условие, указанное в ONпредложении, может быть любым, необязательно использовать первичные ключи (и вам не нужно всегда ссылаться на столбцы из обеих таблиц)! Например:
... ON T1.title = T2.title AND T1.version < T2.version(=> просмотреть этот пост в качестве примера использования: выберите только столбцы с максимальным значением в столбце )... ON T1.y IS NULL... ON 1 = 0 (как образец)Примечание: левое соединение = левое внешнее соединение, правое соединение = правое внешнее соединение.
Простейшие определения
Внутреннее объединение: возвращает сопоставленные записи из обеих таблиц.
Полное внешнее объединение: возвращает сопоставленные и несопоставленные записи из обеих таблиц со значением NULL для несопоставленных записей из обеих таблиц .
Левое внешнее объединение: возвращает сопоставленные и несопоставленные записи только из таблицы на левой стороне .
Правое внешнее объединение: возвращает совпадающие и несопоставленные записи только из таблицы на правой стороне .
Короче говоря
Совпадение + Несоответствие слева + Несоответствие справа = Полное внешнее соединение
Совпадение + Левое Несоответствие = Левое внешнее соединение
Совпадение + Право Несоответствие = Право Наружное соединение
Matched = Inner Join
Проще говоря,
1. INNER JOIN ИЛИ EQUI JOIN: Возвращает набор результатов, который соответствует только условию в обеих таблицах.
2. ВНЕШНЕЕ СОЕДИНЕНИЕ: возвращает набор результатов всех значений из обеих таблиц, даже если условие соответствует или нет.
3. LEFT JOIN: возвращает набор результатов всех значений из левой таблицы и только строк, соответствующих условию в правой таблице.
4. RIGHT JOIN: возвращает набор результатов всех значений из правой таблицы и только строк, соответствующих условию в левой таблице.
5. ПОЛНОЕ СОЕДИНЕНИЕ: полное соединение и полное внешнее соединение - это одно и то же.
Примеры
Предположим, у вас есть две таблицы с одним столбцом и данными следующим образом:
A B
- -
1 3
2 4
3 5
4 6
7
8
Обратите внимание, что (1,2,7,8) являются уникальными для A, (3,4) являются общими и (5,6) являются уникальными для B.
Ключевое слово INNER JOIN выбирает все строки из обеих таблиц, если выполняется условие. Это ключевое слово создаст набор результатов путем объединения всех строк из обеих таблиц, где выполняется условие, т.е. значение общего поля будет одинаковым.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
Результат:
a | b
--+--
3 | 3
4 | 4
Это объединение возвращает все строки таблицы с левой стороны объединения и совпадающие строки для таблицы с правой стороны объединения. Строки, для которых нет подходящей строки на правой стороне, результирующий набор будет содержать нуль. LEFT JOIN также известен как LEFT OUTER JOIN.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
Результат:
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
7 | null
8 | null
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
Результат:
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
ПОЛНОЕ (НАРУЖНОЕ) РЕШЕНИЕ :
FULL JOIN создает результирующий набор, комбинируя результат как LEFT JOIN, так и RIGHT JOIN. Результирующий набор будет содержать все строки из обеих таблиц. Строки, для которых нет соответствия, набор результатов будет содержать значения NULL.
select * from a FULL OUTER JOIN b on a.a = b.b;
Результат:
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
7 | null
8 | null
Внутреннее объединение - внутреннее объединение, использующее любой из эквивалентных запросов, дает пересечение двух таблиц , то есть двух общих строк, которые они имеют.
Левое внешнее соединение - левое внешнее соединение даст все строки в A, а также все общие строки в B.
Полное внешнее объединение - полное внешнее объединение даст вам объединение A и B, т.е. все строки в A и все строки в B. Если что-то в A не имеет соответствующего элемента в B, то часть B ноль, и наоборот
Join is not an intersection unless the tables have the same columnsНет. Вы можете присоединиться к любым столбцам, которые вам нужны, и, если значение совпадает, они объединятся.
1. Внутреннее объединение: также называется присоединением. Возвращает строки, присутствующие как в левой, так и в правой таблице если есть совпадение . В противном случае он возвращает ноль записей.
Пример:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
2. Полное внешнее соединение: также называется полным соединением. Он возвращает все строки, присутствующие как в левой таблице, так и в правой таблице.
Пример:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
3. Левое внешнее соединение: или просто называется левым соединением. Он возвращает все строки, присутствующие в левой таблице и соответствующие строки из правой таблицы (если есть).
4. Правое внешнее соединение: также называется правым соединением. Он возвращает совпадающие строки из левой таблицы (если есть) и все строки, присутствующие в правой таблице.
Преимущества Joins
Рассмотрим ниже 2 таблицы:
EMP
empid name dept_id salary
1 Rob 1 100
2 Mark 1 300
3 John 2 100
4 Mary 2 300
5 Bill 3 700
6 Jose 6 400
отдел
deptid name
1 IT
2 Accounts
3 Security
4 HR
5 R&D
В основном написано как просто JOIN в SQL-запросах. Он возвращает только совпадающие записи между таблицами.
Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
Как вы видите выше, Joseне выводится из EMP на выходе, так как его dept_id 6не находит соответствия в таблице Department. Аналогично HRи R&Dстроки не распечатываются из отдела таблицы , поскольку они не нашли соответствия в таблице EMP.
Таким образом, INNER JOIN или просто JOIN возвращает только совпадающие строки.
Это возвращает все записи из таблицы LEFT и только совпадающие записи из таблицы RIGHT.
Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
6 Jose
Таким образом, если вы наблюдаете вышеприведенный вывод, все записи из таблицы LEFT (Emp) печатаются с совпадающими записями из таблицы RIGHT.
HRи R&Dстроки не выводятся из таблицы Department, так как они не нашли соответствия в таблице Emp в dept_id.
Таким образом, LEFT JOIN возвращает ВСЕ строки из левой таблицы и только совпадающие строки из правой таблицы.
Также можете проверить ДЕМО здесь .
Пожалуйста , смотрите ответ на Мартина Смита за лучшие illustations и объяснения различных соединений, в том числе и в особенности различия между FULL OUTER JOIN, RIGHT OUTER JOINи LEFT OUTER JOIN.
Эти две таблицы образуют основу для представления JOINниже:


SELECT *
FROM citizen
CROSS JOIN postalcode
Результатом будут декартовы произведения всех комбинаций. Никаких JOINусловий не требуется:

INNER JOIN так же, как просто: JOIN

SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
Результатом будут комбинации, удовлетворяющие требуемому JOINусловию:

LEFT OUTER JOIN такой же как LEFT JOIN

SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
Результатом будет все, citizenдаже если нет совпадений postalcode. Снова требуется JOINусловие:

Все примеры были запущены на Oracle 18c. Они доступны на dbfiddle.uk, откуда также пришли скриншоты таблиц.
CREATE TABLE citizen (id NUMBER,
name VARCHAR2(20),
postal NUMBER, -- <-- could do with a redesign to postalcode.id instead.
leader NUMBER);
CREATE TABLE postalcode (id NUMBER,
postal NUMBER,
city VARCHAR2(20),
area VARCHAR2(20));
INSERT INTO citizen (id, name, postal, leader)
SELECT 1, 'Smith', 2200, null FROM DUAL
UNION SELECT 2, 'Green', 31006, 1 FROM DUAL
UNION SELECT 3, 'Jensen', 623, 1 FROM DUAL;
INSERT INTO postalcode (id, postal, city, area)
SELECT 1, 2200, 'BigCity', 'Geancy' FROM DUAL
UNION SELECT 2, 31006, 'SmallTown', 'Snizkim' FROM DUAL
UNION SELECT 3, 31006, 'Settlement', 'Moon' FROM DUAL -- <-- Uuh-uhh.
UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space' FROM DUAL;
JOINиWHERECROSS JOINв результате чего строки в качестве общей идеи / INNER JOIN:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows
Использование CROSS JOINдля получения результата LEFT OUTER JOINтребует трюков, таких как добавление в NULLстроку. Это опущено.
INNER JOINстановится декартовой продукцией. Это так же, как общая идея / CROSS JOIN:
SELECT *
FROM citizen c
JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
Именно здесь внутреннее соединение действительно можно рассматривать как перекрестное соединение с результатами, не соответствующими удаленному условию. Здесь ни одна из полученных строк не удаляется.
Использование INNER JOINдля получения результата LEFT OUTER JOINтакже требует хитростей. Это опущено.
LEFT JOINприводит к строкам как общая идея / CROSS JOIN:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
LEFT JOINприводит к строкам как общая идея / INNER JOIN:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode
Поиск в интернете по изображению "sql join cross inner external" покажет множество диаграмм Венна. Раньше у меня была печатная копия одного на моем столе. Но есть проблемы с представительством.
Диаграмма Венна отлично подходит для теории множеств, где элемент может быть в одном или обоих наборах. Но для баз данных мне кажется, что элемент в одном «наборе» является строкой в таблице и, следовательно, не присутствует ни в каких других таблицах. Нет такой вещи, как одна строка присутствует в нескольких таблицах. Строка уникальна для таблицы.
Самостоятельные объединения - это угловой случай, когда каждый элемент фактически одинаков в обоих наборах. Но это все еще не свободно ни от одной из проблем ниже.
Набор Aпредставляет собой набор слева ( citizenтаблица), а набор B- это набор справа ( postalcodeтаблица) в обсуждении ниже.
Каждый элемент в обоих наборах сопоставляется с каждым элементом в другом наборе, что означает, что нам нужно Aколичество каждого Bэлемента и Bколичество каждого Aэлемента, чтобы правильно представить этот декартово произведение. Теория множеств не создана для нескольких идентичных элементов в наборе, поэтому я считаю, что диаграммы Венна правильно представляют ее непрактично / невозможно. Кажется, что это совсем не UNIONподходит.
Строки различны. Всего UNION7 строк. Но они несовместимы для общего SQLнабора результатов. И это совсем не так CROSS JOIN:

Попытка представить это так:

..но теперь это просто выглядит как INTERSECTION, что это, конечно, нет . Кроме того, в этом элементе нет ни INTERSECTIONодного из двух различных наборов. Тем не менее, это очень похоже на результаты поиска, похожие на это:

Для справки один результат поиска для CROSS JOINs можно увидеть на Tutorialgateway . Как INTERSECTIONи этот, пуст.
Значение элемента зависит от JOINусловия. Это можно представить при условии, что каждая строка становится уникальной для этого условия. Значение id=xверно только для одного ряда. Как только строка в table A( citizen) соответствует нескольким строкам в table B( postalcode) при JOINусловии, результат имеет те же проблемы, что и CROSS JOIN: Строка должна быть представлена несколько раз, и теория множеств на самом деле не создана для этого. Хотя при условии уникальности диаграмма может работать, но имейте в виду, что это JOINусловие определяет размещение элемента на диаграмме. Глядя только на значения JOINусловия с остальной частью ряда только для поездки:

Это представление полностью расходится при использовании INNER JOINс ON 1 = 1условием, превращающим его в CROSS JOIN.
С self- JOIN, строки на самом деле являются идентичными элементами в обеих таблицах, но представляют таблицы как обе Aи Bне очень подходят. Например , общее само JOINусловие , которое делает элемент Aбудет сопрягать иной элемент в В ON A.parent = B.child, что делает матч с Aчтобы Bна отдельно элементах. Из примеров, которые будут SQLпохожи на это:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader

То есть Смит - лидер и Грина, и Дженсена.
Опять проблемы начинаются, когда одна строка имеет несколько совпадений со строками в другой таблице. Это дополнительно усложняется тем, что OUTER JOINможет соответствовать пустому набору. Но в теории множеств объединение любого множества Cи пустого множества всегда справедливо C. Пустой набор ничего не добавляет. Представление этого LEFT OUTER JOINобычно просто показывает все, Aчтобы проиллюстрировать, что строки Aвыбираются независимо от того, есть совпадение или нет B. Однако у «совпадающих элементов» есть те же проблемы, что и на иллюстрации выше. Они зависят от состояния. И пустой набор, кажется, забрел к A:

Нахождение всех строк CROSS JOINсо Смитом и почтовым индексом на Луне:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';

Теперь диаграмма Венна не используется для отражения JOIN. Используется только для WHEREпредложения:

... и это имеет смысл.
Как объяснил, это INNER JOINне совсем INTERSECT. Однако INTERSECTs можно использовать по результатам отдельных запросов. Здесь диаграмма Венна имеет смысл, поскольку элементы отдельных запросов на самом деле являются строками, которые либо принадлежат только одному из результатов, либо обоим. Очевидно, что Intersect будет возвращать результаты только в том случае, если строка присутствует в обоих запросах. Это SQLприведет к тому же ряду, что и приведенный выше WHERE, и диаграмма Венна также будет такой же:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
INTERSECT
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
Ан OUTER JOINне а UNION. Однако UNIONработают в тех же условиях INTERSECT, что и возвращают все результаты, объединяющие оба параметра SELECT:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
UNION
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
что эквивалентно:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
..и дает результат:

Также здесь имеет смысл диаграмма Венна:

Важным примечанием является то, что они работают только тогда, когда структура результатов двух SELECT одинакова, что позволяет сравнивать или объединять. Результаты этих двух не позволят это:
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
.. пытается объединить результаты с UNIONдает
ORA-01790: expression must have same datatype as corresponding expression
Для дальнейшего интереса прочитайте Скажите НЕТ диаграммам Венна при объяснении СОЕДИНЕНИЙ, и соединения sql как диаграмму Венна . Оба также покрывают EXCEPT.
Здесь есть много хороших ответов с очень точными примерами реляционной алгебры . Вот очень упрощенный ответ, который может быть полезен для начинающих или начинающих программистов с дилеммами кодирования SQL.
В основном, чаще всего запросы JOINсводятся к двум случаям:
Для SELECTподмножества данных A:
INNER JOINкогда связанные данные, которые Bвы ищете, ДОЛЖНЫ существовать для каждого проекта базы данных;LEFT JOINкогда связанные данные, которые Bвы ищете MIGHT или MIGHT NOT, существуют для каждого проекта базы данных.Разница между inner joinи outer joinзаключается в следующем:
Inner joinэто объединение, объединяющее таблицы на основе совпадающих кортежей, тогда outer joinкак объединение, объединяющее таблицы на основе сопоставленного и несопоставленного кортежа.Inner joinобъединяет совпавшую строку из двух таблиц, в которой пропущены несопоставленные строки, тогда как outer joinобъединяет строки из двух таблиц, и несопоставленные строки заполняются нулевым значением.Inner joinэто как операция пересечения, тогда как outer joinэто как операция объединения.Inner joinэто два типа, тогда outer joinкак три типа.outer joinбыстрее чем inner join.