В чем разница между "INNER JOIN" и "OUTER JOIN"?

Также как подходят LEFT JOIN, RIGHT JOIN и FULL JOIN?

Из ответов, комментариев и ссылок на них ниже только один фактически объясняет, как диаграммы Венна представляют операторы: Область пересечения круга представляет набор строк в A JOIN B. Область, уникальная для каждого круга, представляет набор строк, которые вы получаете, беря его таблицу строки, которые не участвуют в A JOIN B, и добавление столбцов, уникальных для другой таблицы, имеют значение NULL. (И большинство дает смутное фиктивное соответствие кружков A и B.)

philipxy 19.10.2014 00:24

@DanteTheSmith: Нет, здесь те же проблемы, что и на диаграммах. См. Мой комментарий выше по поводу вопроса, а ниже по поводу того самого сообщения в блоге: «Джефф отказывается от своего блога на несколько страниц ниже в комментариях». Диаграммы Венна показывают элементы в наборах. Просто постарайтесь точно определить, что это за наборы и какие элементы изображены на этих диаграммах. Наборы не таблиц и элементы не их строк. Также любые две таблицы могут быть объединены, поэтому PK и FK не имеют отношения. Все подделка. Вы делаете то же самое, что и тысячи других - получили смутное впечатление у вас (ошибочно) предполагать имеет смысл.

philipxy 18.05.2017 08:57

Мой предыдущий комментарий касается сбитый с толку отказ от авторства Джеффа Этвуда в блоге.

philipxy 24.01.2021 02:15

Ссылка на мой 1-й комментарий является внешней, но на i.stack.imgur.com есть постоянные копии иллюстраций вывод (не ввод) для соединений внутренний, оставили и полный (выделены зеленым цветом).

philipxy 27.02.2021 07:37
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
4 847
4
2 403 139
25
Перейти к ответу Данный вопрос помечен как решенный

Ответы 25

Внутреннее соединение показывает строки, только если есть соответствующая запись на другой (правой) стороне соединения.

Внешнее соединение (слева) показывает строки для каждой записи с левой стороны, даже если на другой (правой) стороне соединения нет совпадающих строк. Если нет соответствующей строки, столбцы для другой (правой) стороны будут показывать NULL.

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

Внешние соединения будут возвращать записи для левой стороны, даже если для правой стороны ничего не существует.

Например, у вас есть таблицы Orders и OrderDetails. Они связаны с помощью «OrderID».

Заказы

  • Номер заказа
  • Имя Клиента

Информация для заказа

  • OrderDetailID
  • Номер заказа
  • Наименование товара
  • Кол-во
  • Цена

Запрос

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). Насчет дополнительных условий не знала, они хорошо сочетаются ...

PhiLho 05.01.2013 15:11
Ответ принят как подходящий

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

  • Внутреннее соединение A и B дает результат пересечения A с B, то есть внутренней части пересечения Диаграмма Венна.

  • Внешнее соединение A и B дает результат объединения A 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

Было бы хорошо дополнить этот пример, добавив еще одну строку в таблице B со значением 4. Это покажет, что внутренние соединения не обязательно должны быть равными по количеству строк.

softveda 30.08.2009 16:59

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

Thomas 03.05.2011 23:57

да отличное и отличное объяснение. но почему в столбце b значения не в порядке? т.е. это 6,5, а не 5,6?

Ameer 04.03.2013 12:39

@Ameer, спасибо. Присоединение не гарантирует заказ, вам нужно будет добавить предложение ORDER BY.

Mark Harrison 05.03.2013 04:28

Томас: На самом деле, вы и Марк ошиблись насчет другой части формулировки. «Внешние части диаграммы Венна» относятся к «A U B \ A ∩ B». Итак, Марк случайно прямо противоречил самому себе, хотя оставшаяся часть его объяснения, очевидно, была достаточно ясной, чтобы компенсировать это.

codetaku 12.08.2013 18:56

Сказать, что внешнее соединение является союз, может показаться немного запутанным, если в результирующем наборе A left outer join B нет несовпадающих элементов B. Не так ли?

Birupakhya Dash 15.01.2014 20:35

«Предполагая, что вы присоединяетесь к столбцам без дубликатов, что является очень частым случаем:» - Сильно ли меняется, когда это не так?

jdero 02.07.2014 23:30

Соединение не дает вам объединения или пересечения чего-либо. Это дает вам замыкание в решетке.

nomen 01.08.2014 20:09

Синтаксис + никогда не был ANSI, это был Oracle, и он всегда был неадекватным для выражений, использующих несколько таблиц или сравнений. Синтаксис ON - ANSI. PS Сравнение с диаграммами Венна сформулировано неправильно. См. Мой комментарий к вопросу.

philipxy 20.01.2016 09:09

Вот правильное утверждение для пересечения / объединения круги / наборы A и B в терминах столы A и B. Круг A = A LEFT JOIN B ON условие. Круг B = (A RIGHT JOIN B ON условие). (A FULL OUTER JOIN B на условие) = Окружность A СОЕДИНЕНИЕ Окружность B. (A INNER JOIN B ON * условие) = Обведите A INTERSECT Circle B. Обведите A MINUS Circle B = (Строки, не совпадающие с A JOIN B, расширены NULL). Круг B МИНУС Круг A = (B строк, не совпадающих с A JOIN B, расширены NULL). См. Мой комментарий (первый) к вопросу.

philipxy 18.06.2016 01:44

@HelenNeely К сожалению, это объяснение неверно. Его маркеры верны только тогда, когда все столбцы одинаковы, а язык нечеткий. Смотрите мой комментарий непосредственно перед вашим и мой комментарий по вопросу.

philipxy 24.07.2017 15:43

@Damian да, OUTER JOIN и FULL OUTER JOIN эквивалентны, а LEFT / RIGHT JOIN эквивалентны LEFT / RIGHT OUTER JOIN, так же, как INNER JOIN эквивалентно простому JOIN

Chris 30.01.2019 01:26

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

Colm Bhandal 03.05.2020 10:00

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 без дублирования.

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

В OUTER JOIN результирующая таблица может иметь пустые столбцы. Внешнее соединение может быть LEFT или RIGHT.

LEFT OUTER JOIN возвращает все строки из первой таблицы, даже если во второй таблице нет совпадений.

RIGHT OUTER JOIN возвращает все строки из второй таблицы, даже если в первой таблице нет совпадений.

Простыми словами:

внутреннее соединение извлекает только совпавшие строки.

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

  • Оставили: совпадают строки в правой таблице и все строки в левой таблице

  • Правильно: совпадают строки в левой таблице и все строки в правой таблице или

  • Полный: все строки во всех таблицах. Неважно, есть совпадение или нет

@nomen Не то, чтобы этот ответ обращался к нему, но INNER JOIN - это пересечение, а FULL OUTER JOIN - это соответствующий UNION если, левый и правый наборы / круги содержат строки (соответственно) LEFT и RIGHT JOIN. PS Этот ответ неясен относительно строк на входе и выходе. Он путает «в левой / правой таблице» с «имеет левую / правую часть в левой / правой» и использует «совпадающую строку» против «все» для обозначения строки, расширенной строкой из другой таблицы против нулей.

philipxy 29.11.2015 04:17

Я не вижу много подробностей о производительности и оптимизаторе в других ответах.

Иногда полезно знать, что только INNER JOIN является ассоциативным, что означает, что оптимизатор имеет больше возможностей поиграть с ним. Он может изменить порядок соединения, чтобы ускорить его и сохранить тот же результат. Оптимизатор может использовать большинство режимов соединения.

Как правило, рекомендуется использовать INNER JOIN вместо других типов соединений. (Конечно, если это возможно с учетом ожидаемого набора результатов.)

Вот несколько хороших примеров и объяснений этого странного ассоциативного поведения:

Наверное, не может быть хорошей практикой использовать один тип соединения вместо другого. От того, какое соединение вы используете, зависит, какие данные вы хотите использовать. Если вы используете другой, вы ошибаетесь. К тому же, в Oracle, по крайней мере, этот ответ совершенно неверен. Это звучит совершенно неправильно, и у вас нет доказательств. У тебя есть доказательства?

Ben 26.12.2014 11:51

1. Я имею ввиду пытаться использовать. Я видел, как много людей используют соединения LEFT OUTER повсюду без какой-либо уважительной причины. (Объединенные столбцы были «не нулевыми».) В таких случаях определенно было бы лучше использовать ВНУТРЕННИЕ объединения. 2. Я добавил ссылку, объясняющую неассоциативное поведение лучше, чем я мог бы.

Lajos Veres 26.12.2014 14:01

Насколько я знаю, INNER JOIN в большинстве случаев медленнее, чем LEFT JOIN, и люди могут использовать LEFT JOIN вместо INNER JOIN, добавив WHERE для удаления неожиданных результатов NULL;).

shA.t 13.05.2015 06:01

Эти комментарии заставили меня немного сомневаться. Как вы думаете, почему INNER медленнее?

Lajos Veres 13.05.2015 11:04

Зависит от двигателя. gnu join, joinkeys, DB2, MySQL. Существует множество ловушек производительности, таких как нечеткая типизация или явное приведение типов.

mckenzm 10.07.2019 05:03

Внутреннее соединение

Получить только совпавшие строки, то есть A intersect B.

Enter image description here

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Левое внешнее соединение

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

Enter image description here

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Полное внешнее соединение

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

Enter image description here

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Рекомендации

Как называется инструмент? Я нахожу это интересным, так как показывает количество строк и диаграмм Венна.

Grijesh Chauhan 27.01.2014 16:23

@GrijeshChauhan Да, но вы можете попробовать запустить его с помощью вино.

Tushar Gupta - curioustushar 27.01.2014 16:30

Ох! да я .. я использовал SQLyog с вином .. есть еще PlayOnLinux

Grijesh Chauhan 27.01.2014 16:32

Ваш текст нечеткий и неправильный. «Только совпавшие строки» - это строки из перекрестного соединения A и B, и то, что извлекается (внутреннее соединение B), не является пересечением A B, а (A левое соединение B) пересекает (A правое соединение B). «Выбранные» строки взяты не из A и B, они из A перекрестного соединения B и из расширенных нулем значений строк из A и B.

philipxy 24.07.2018 04:09

@ TusharGupta-curioustushar вам следует включить «Таблицы, используемые для примеров SQL»

Manuel Jordan 17.10.2019 16:52

«Получить только совпавшие строки, то есть A пересекает B.» Это не правильно.

Colm Bhandal 07.05.2020 21:35

Внутреннее соединение.

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

Внешнее соединение.

оставил присоединиться пытается найти совпадение строк из первой таблицы со строками во второй таблице. Если совпадение не найдено, оно вернет столбцы из первой таблицы и оставит столбцы из второй таблицы пустыми (пустыми).

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

Внутреннее соединение:- Внутреннее соединение создает новую таблицу результатов путем объединения значений столбцов двух таблиц (Наемный рабочий и Место расположения) на основе предиката соединения. Запрос сравнивает каждую строку Наемный рабочий с каждой строкой Место расположения, чтобы найти все пары строк, которые удовлетворяют предикату соединения. Когда предикат соединения удовлетворяется путем сопоставления значений, отличных от NULL, значения столбцов для каждой сопоставленной пары строк Наемный рабочий и Место расположения объединяются в строку результата. Вот как будет выглядеть SQL для внутреннего соединения:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Теперь вот как будет выглядеть результат выполнения этого SQL:

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

Левое внешнее соединение: - Результат левого внешнего соединения (или просто левого соединения) для таблиц Наемный рабочий и Место расположения всегда содержит все записи «левой» таблицы (Наемный рабочий), даже если условие соединения не находит ни одной совпадающей записи в «правой» таблице. (Место расположения). Вот как будет выглядеть SQL для левого внешнего соединения, используя приведенные выше таблицы:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Теперь вот как будет выглядеть результат выполнения этого SQL:

Правое внешнее соединение: - Правое внешнее соединение (или правое соединение) очень похоже на левое внешнее соединение, за исключением того, что обработка таблиц была обратной. Каждая строка из «правой» таблицы (Место расположения) появится в объединенной таблице хотя бы один раз. Если подходящей строки из «левой» таблицы (Наемный рабочий) не существует, NULL появится в столбцах из Наемный рабочий для тех записей, которые не совпадают в Место расположения. Вот как выглядит SQL:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

Используя приведенные выше таблицы, мы можем показать, как будет выглядеть результирующий набор правого внешнего соединения:

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

Источник изображения

Справочное руководство MySQL 8.0 - Синтаксис соединения

Операции Oracle Join

лучший ответ на данный момент, альтернативный синтаксис - это то, что я искал, спасибо!

Joey 08.09.2019 11:21

Диаграммы Венна помечены неправильно. Смотрите мои комментарии к вопросу и другие ответы. Также большая часть этого языка бедна. Например: «Когда предикат соединения удовлетворяется путем сопоставления значений, отличных от NULL, значения столбцов для каждой сопоставленной пары строк Employee и Location объединяются в строку результатов». Нет, не «Когда удовлетворяется предикат соединения путем сопоставления значений, отличных от NULL». Значения в строках не имеют значения, кроме того, является ли условие в целом истинным или ложным. Некоторые значения вполне могут быть NULL для истинного условия.

philipxy 06.11.2019 10:00

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

philipxy 08.05.2020 22:42

Простыми словами:

Внутреннее соединение -> Возьмите ТОЛЬКО общие записи из родительской и дочерней таблиц, ГДЕ первичный ключ родительской таблицы совпадает с внешним ключом в дочерней таблице.

Левое присоединение ->

псевдокод

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 с правой стороны в Right join, вы получите тот же результат, что и LEFT JOIN.

Внешнее соединение: Показать все записи в обеих таблицах No matter what. Если записи в левой таблице не соответствуют правой таблице на основе первичного, внешнего ключа, используйте значение NULL как результат соединения.

Пример :

Example

Предположим теперь для 2 столов

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

Здесь таблица сотрудников - это главная таблица, 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;

Схематично это выглядит так:

Diagram

Результат не имеет ничего общего (как такового) с первичными / уникальными / кандидатными ключами и внешними ключами. Бавиур можно и нужно описывать без ссылки на них. Вычисляется перекрестное соединение, затем строки, не соответствующие условию ON, отфильтровываются; дополнительно для внешних объединений строки отфильтрованные / несовпадающие строки расширяются на NULL (на LEFT / RIGHT / FULL и включены.

philipxy 10.08.2015 07:27

Предположение, что соединения SQL всегда совпадают по первичным / внешним ключам, приводит к неправильному использованию диаграмм Венна. Пожалуйста, измените свой ответ соответствующим образом.

Colm Bhandal 07.05.2020 21:37

Ответ заключается в значении каждого из них, поэтому в результатах.

Note :
In SQLite there is no RIGHT OUTER JOIN or FULL OUTER JOIN.
And also in MySQL there is no FULL OUTER JOIN.

Мой ответ основан на вышеупомянутом Примечание.

Когда у вас есть две такие таблицы:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

ПЕРЕКРЕСТНОЕ / ВНЕШНЕЕ СОЕДИНЕНИЕ:
У вас могут быть данные всех этих таблиц с 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:
(Для ПРАВО ПРИСОЕДИНИТЬСЯ просто поменяйте место таблиц)

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:

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

Ну, по вашему желанию вы выбираете каждый, который соответствует вашим потребностям;).

К заметке можно добавить, что в MySQL тоже нет full outer join.

potashin 14.06.2015 16:34

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

Хотя ответ @Martin Smith во многом является лучшим из этой группы, он показывает только ключевой столбец из каждой таблицы, тогда как я думаю, что в идеале также должны отображаться неключевые столбцы.

Лучшее, что я мог сделать за отведенные полчаса, я все еще не думаю, что это адекватно показывает, что есть нули из-за отсутствия ключевых значений в TableB или что OUTER JOIN на самом деле является объединением, а не объединением:

Вопрос спрашивает разницу между ВНУТРЕННИМ и ВНЕШНИМ объединениями, хотя не обязательно левое внешнее соединение lol

LearnByReading 22.01.2016 22:32

@LearnByReading: мое изображение справа - это правое внешнее соединение, т.е. заменить TableA a LEFT OUTER JOIN TableB b на TableB B RIGHT OUTER JOIN TableA a

onedaywhen 29.04.2019 10:58
  • Внутреннее соединение - внутреннее соединение с использованием любого из эквивалентных запросов дает пересечение двух столы, то есть двух общих строк.

  • Левое внешнее соединение - левое внешнее соединение предоставит все строки в A плюс любые общие строки в B.

  • Полное внешнее соединение - A полное внешнее соединение даст вам объединение A и B, то есть все строки в A и все строки в B. Если что-то в A не имеет соответствующей базы данных в B, тогда часть B равна нулю, и наоборот. наоборот

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

philipxy 03.02.2017 14:15

@philipxy: Не согласен с вашим утверждением Join is not an intersection unless the tables have the same columns Нет. Вы можете объединить любые столбцы, которые хотите, и если значение совпадет, они будут объединены.

SuicideSheep 11.04.2017 12:23

Этот комментарий столь же неясен, как и ваш ответ. (Я полагаю, вы могли подумать что-то вроде того, что набор значений вложенных строк для общих столбцов результата является пересечением наборов значений вложенных строк для общих столбцов каждого из входов; но это не то, что вы написали. непонятны.)

philipxy 11.04.2017 17:24

Я имел в виду, что соединение - это только пересечение входов, когда это естественное внутреннее соединение входов с одними и теми же столбцами. Вы неправильно используете слова «пересечение» и «союз».

philipxy 05.02.2020 15:34

Простейшие определения

Внутреннее соединение: возвращает совпадающие записи из обеих таблиц.

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

Левое внешнее соединение: возвращает совпадающие и несопоставленные записи только из таблицы на Левая сторона.

Правое внешнее соединение: возвращает совпадающие и несопоставленные записи только из таблицы на Правая сторона.

Короче

Совпадение + Несовпадение влево + Несопоставление вправо = Полное внешнее соединение

Совпадение + Несовпадение влево = Левое внешнее соединение

Совпадение + Несовпад справа = Правое внешнее соединение

Соответствует = Внутреннее соединение

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

yeliabsalohcin 05.09.2017 12:22

@yeliabsalohcin Вы не объясняете «как ожидалось» здесь или «работает» в своем комментарии к вопросу. Это просто какое-то необъяснимое личное заблуждение, которого вы странно ожидаете от других. Если вы относитесь к словам так же небрежно, когда читаете - неверно истолковываете четкое письмо и / или принимаете нечеткое письмо - как когда вы пишете здесь, то вы можете ожидать неправильных представлений. На самом деле этот ответ, как и большинство здесь, неясен и неверен. «Внутреннее объединение: возвращает совпадающие записи из обеих таблиц» неверно, если наборы входных столбцов различаются. Это пытающийся, чтобы сказать что-то определенное, но это не. (См. Мой ответ.)

philipxy 22.11.2017 05:52

Проще говоря,

1.ВНУТРЕННЕЕ СОЕДИНЕНИЕ ИЛИ ЭКВИ СОЕДИНЕНИЕ: Возвращает набор результатов, который соответствует только условию в обеих таблицах.

2.ВНЕШНЕЕ СОЕДИНЕНИЕ: Возвращает набор результатов всех значений из обеих таблиц, даже если есть соответствие условий или нет.

3.ЛЕВАЯ ПРИСОЕДИНИТЬСЯ: Возвращает набор результатов всех значений из левой таблицы и только строк, которые соответствуют условию в правой таблице.

4.ПРАВО ПРИСОЕДИНИТЬСЯ: Возвращает набор результатов всех значений из правой таблицы и только строк, которые соответствуют условию в левой таблице.

5.ПОЛНОЕ СОЕДИНЕНИЕ: Полное соединение и полное внешнее соединение - это одно и то же.

Точный алгоритм для INNER JOIN, LEFT/RIGHT OUTER JOIN следующий:

  1. Возьмите каждую строку из первой таблицы: a
  2. Рассмотрим все строки из второй таблицы рядом с ней: (a, b[i])
  3. Оцените предложение ON ... для каждой пары: ON( a, b[i] ) = true/false?
    • Когда условие оценивается как true, верните эту объединенную строку (a, b[i]).
    • При достижении конца второй таблицы без какого-либо соответствия, а это Outer Join, возвратите пару (виртуальный), используя Null для всех столбцов другой таблицы: (a, Null) для ЛЕВОГО внешнего соединения или (Null, b) для ПРАВОГО внешнего соединения. Это необходимо для того, чтобы в окончательных результатах присутствовали все строки первой таблицы.

Примечание: условие, указанное в предложении ON, может быть любым, не требуется использовать Первичные ключи (и вам не нужно всегда ссылаться на столбцы из обеих таблиц)! Например:

Inner Join vs. Left Outer Join


Примечание: Левое соединение = левое внешнее соединение, правое соединение = правое внешнее соединение.

1.Внутреннее соединение: Также называется присоединением. Он возвращает только строки, присутствующие как в левой таблице, так и в правой таблице если есть совпадение. В противном случае он возвращает нулевые записи.

Пример:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

output1

2.Полное внешнее соединение: Также называется полным соединением. Он возвращает все строки, присутствующий как в левой, так и в правой таблице.

Пример:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

output2

3.Левое внешнее соединение: Или просто левое соединение. Он возвращает все строки, присутствующие в левой таблице, и соответствующие строки из правой таблицы (если есть).

4.Правое внешнее соединение: Также называется правым соединением. Он возвращает совпадающие строки из левой таблицы (если есть) и все строки, присутствующие в правой таблице.

joins

Преимущества объединений

  1. Выполняется быстрее.

Это правильно, только если в таблицах есть одинаковый набор столбцов. (Это путает внутреннее соединение с пересечением, а полное соединение - с объединением.) Также "совпадение" не определено. Прочтите мои другие комментарии.

philipxy 24.07.2017 16:02

По этой теме много дезинформации, в том числе здесь, в Stack Overflow.

left join on (также известный как left outer join on) возвращает строки inner join on. union all несопоставленные строки левой таблицы, расширенные null.

right join (on aka right outer join on) возвращает строки inner join on. union all несопоставленные правые строки таблицы, расширенные nulls.

full join on (также известный как full outer join on) возвращает строки inner join on; union all несопоставленные строки левой таблицы, расширенные null; union all; несопоставленные строки таблицы справа, расширенные null.

(Стандарт SQL 2006, правила синтаксиса SQL / Foundation 7.7 1, общие правила 1 b, 3 c и d, 5 b.)

Так что не используйте outer join, пока не узнаете, в чем задействован базовый inner join.


Узнайте, какие строки возвращает inner join on:
CROSS JOIN vs INNER JOIN в SQL

Это также объясняет, почему (-подобные) диаграммы Венна бесполезны для внутреннего и внешнего соединения. Подробнее о том, почему диаграммы Венна (-подобные) не полезны для объединений:
Диаграмма Венна для естественного соединения

Я действительно прочитал много ваших комментариев. Когда вы говорите, что «диаграмма Венна при правильной интерпретации может представлять внутреннее и внешнее соединение», вы имеете в виду, когда ее правильно интерпретирует наблюдатель или сама диаграмма Венна? Если второе, нарисуйте его :)

onedaywhen 24.04.2019 19:08

Я не уверен, что вы пытаетесь сказать. Я говорю о стандартной интерпретации диаграммы Венна как набора элементов. (Потому что некоторые виды использования диаграмм даже не справляются с этим.) «Правильно» для приложения включает в себя указание, что такое наборы и / или элементы. См. Комментарий вверху этой страницы с 50 голосами за диаграмму Венна для внутренних и внешних соединений. Я отредактирую некоторые свои комментарии к этому вопросу. Мне не нужна диаграмма Венна в этом посте.

philipxy 24.04.2019 19:31

Я тоже не хочу диаграмм Венна!

onedaywhen 25.04.2019 18:52

Я должен признать, что, несмотря на мои быстрые формулировки в комментариях, поскольку SQL включает в себя пакеты и нули, а культура SQL не имеет общей терминологии для обозначения и различения соответствующих понятий, нетривиально даже четко объяснить, как элементы диаграммы Венна 1: 1 с выходными «строками», не говоря уже о входных «строках». Или что делают внутренние или внешние соединения, не говоря уже об их различии. "value" может включать или не включать NULL, "row" может быть списком значений по сравнению с слотом в значении таблицы или переменная & "=" может быть SQL "=" с равенством.

philipxy 25.04.2019 20:44

Подобно нашему обсуждению декартовых продуктов и реляционных продуктов, я подозреваю, что это тот случай, когда диаграммы Венна имеют большой смысл для людей, которые уже понимают различия между типами соединений!

onedaywhen 29.04.2019 10:51

В случае «реляционного декартова произведения» это стандартное и разумное название для определенной вещи, которую люди обычно понимают и которая обоснованно описывается как похожая на декартово произведение. В случае диаграмм Венна SQL они не имеют смысла, люди просто предполагают, что они есть, независимо от того, понимают ли они операторы / различия.

philipxy 29.04.2019 14:15

Разница между inner join и outer join заключается в следующем:

  1. Inner join - это соединение, которое объединяет таблицы на основе совпадающих кортежей, тогда как outer join - это соединение, которое объединяет таблицу на основе как совпавших, так и несопоставленных кортежей.
  2. Inner join объединяет совпавшие строки из двух таблиц, в которых несопоставленные строки опущены, тогда как outer join объединяет строки из двух таблиц, и несогласованные строки заполняются нулевым значением.
  3. Inner join похож на операцию пересечения, тогда как outer join похож на операцию объединения.
  4. Inner join бывает двух типов, а outer join - трех типов.
  5. outer join быстрее, чем inner join.

Результат внешнего соединения такой же, как и при внутреннем соединении, но плюс несколько дополнительных строк, поэтому я понятия не имею, почему вы думаете, что внешнее соединение будет быстрее. И что это за «два типа» внутреннего соединения? Я полагаю, вы имеете в виду полное, левое и правое внешнее?

Martin Smith 09.01.2020 17:07

Внешнее соединение не быстрее внутреннего.

philipxy 09.01.2020 17:10

  • INNER JOIN - наиболее типичное объединение двух или более таблиц. Он возвращает совпадение данных как для таблицы ON, так и для отношения forignkey.
  • OUTER JOIN такой же, как INNER JOIN, но он также включает данные NULL в ResultSet.
    • LEFT JOIN = INNER JOIN + Несогласованные данные таблицы оставили с соответствием Null в правой таблице.
    • RIGHT JOIN = INNER JOIN + Несогласованные данные таблицы верно с соответствием Null в левой таблице.
    • FULL JOIN = INNER JOIN + Несогласованные данные в таблицах и справа, и слева с совпадениями Null.
  • Самосоединение не является ключевым словом в SQL, когда таблица ссылается на данные, которые сами по себе известны как самосоединение. Используя 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 

Рассмотрим ниже 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

Внутреннее соединение:

В основном записывается как ПРИСОЕДИНИТЬСЯ в 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 возвращает только совпадающие строки.

ЛЕВАЯ ПРИСОЕДИНИТЬСЯ:

Это возвращает все записи из ЛЕВОЙ таблицы и только совпадающие записи из ПРАВОЙ таблицы.

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 не печатаются из таблицы отделение, поскольку они не нашли совпадения в таблице Emp на dept_id.

Итак, LEFT JOIN возвращает ВСЕ строки из таблицы Left и только соответствующие строки из таблицы RIGHT.

Также можете проверить DEMO здесь.

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

По сути, чаще всего запросы JOIN сводятся к двум случаям:

Для SELECT из подмножества данных A:

  • используйте INNER JOIN, когда соответствующие данные B, которые вы ищете ДОЛЖЕН, существуют для каждого проекта базы данных;
  • используйте LEFT JOIN, когда соответствующие данные B, которые вы ищете МОГ БЫ или МОЖЕТ НЕ, существуют для каждого проекта базы данных.

В SQL есть два основных типа JOIN: [INNER и OUTER]


Примеры

Предположим, у вас есть две таблицы с одним столбцом в каждой и следующие данные:

A    B
-    -
1    3
2    4
3    5
4    6
7
8

Обратите внимание, что (1,2,7,8) уникальны для A, (3,4) являются общими, а (5,6) уникальны для B.



  • (ВНУТРЕННЕЕ СОЕДИНЕНИЕ:

Ключевое слово INNER JOIN выбирает все строки из обеих таблиц, пока выполняется условие. Это ключевое слово создаст набор результатов путем объединения всех строк из обеих таблиц, которым удовлетворяет условие, т.е. значение общего поля будет одинаковым.

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


  • ЛЕВЫЙ (ВНЕШНИЙ) ПРИСОЕДИНИТЬСЯ:

Это соединение возвращает все строки таблицы с левой стороны соединения и соответствующие строки для таблицы с правой стороны соединения. Строки, для которых нет соответствующей строки с правой стороны, набор результатов будет содержать null. LEFT JOIN также известен как LEFT OUTER JOIN.

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


  • ПРАВО (ВНЕШНИЙ) ПРИСОЕДИНИТЬСЯ: возвращает все записи из правой таблицы и соответствующие записи из левой таблицы.

RIGHT JOIN / RIGHT OUTER JOIN

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.

FULL JOIN / FULL OUTER JOIN

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

Диаграмм Венна недостаточно для описания SQL-соединений в общем случае. Соединения SQL не обязательно должны соответствовать строкам между таблицами один к одному, например использование внешнего ключа по сравнению с первичным ключом.

Colm Bhandal 07.05.2020 21:48

Как соединить 2 таблицы без совпадения строки? Вам понадобится первичный или внешний ключ столбца или какое-то общее поле, чтобы вы могли выполнить соединение. Мне интересно, почему вы проголосовали против этого ответа. И диаграмма Венна является источником, объясняющим, как работает SQL JOIN. У вас есть лучшие примеры для представления объединений? Если нет, проголосуйте за него, чтобы люди получили лучшие решения. Спасибо.

Mayur 08.05.2020 09:18

Вы тот, кто размещает диаграммы в посте. Какая легенда к схемам? - Каковы элементы каждого набора? А как насчет того, что столы - это сумки, а не наборы? Вы не говорите. Одна вещь, которой они не являются, - это ряды A и B на этикетках. Смотрите мои комментарии к сообщениям на этой странице. Этот пост просто слепо повторяет неправильное использование, которое видели в другом месте, но не поняли или не подвергли сомнению. Также то, что вы говорите здесь в тексте, непонятно и неверно. Кроме того, это ничего не добавляет ко многим уже здесь ответам. (Несмотря на то, что почти все они довольно плохие.) PS Уточняйте, пожалуйста, правки, а не комментарии.

philipxy 08.05.2020 23:12

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

philipxy 10.05.2020 05:10

Объединения легче объяснить на примере:

Чтобы смоделировать людей и электронные письма, хранящиеся в отдельных таблицах,

Таблица A и Таблица B объединены Table_A.я бы = Table_B.name_id

Внутреннее соединение

Отображаются только строки с совпадающими идентификаторами.

Внешние соединения

Отображаются совпадающие идентификаторы и несоответствующие строки для Таблица А.

Отображаются совпадающие идентификаторы и несоответствующие строки для Таблица B.

Отображаются совпадающие идентификаторы и несовпадающие строки из обеих таблиц.

Примечание: полное внешнее соединение недоступно в MySQL.

Другие вопросы по теме