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


Внутреннее соединение показывает строки, только если есть соответствующая запись на другой (правой) стороне соединения.
Внешнее соединение (слева) показывает строки для каждой записи с левой стороны, даже если на другой (правой) стороне соединения нет совпадающих строк. Если нет соответствующей строки, столбцы для другой (правой) стороны будут показывать 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). Насчет дополнительных условий не знала, они хорошо сочетаются ...
Предполагая, что вы присоединяетесь к столбцам без дубликатов, что является очень распространенным случаем:
Внутреннее соединение 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. Это покажет, что внутренние соединения не обязательно должны быть равными по количеству строк.
Отличное объяснение, однако это утверждение: Внешнее соединение A и B дает результат объединения A B, то есть внешних частей объединения диаграмм Венна. сформулировано неточно. Внешнее соединение даст результаты A пересечения B в дополнение к одному из следующих: все A (левое соединение), все B (правое соединение) или все A и все B (полное соединение). Только этот последний сценарий на самом деле является союзом B. Тем не менее, хорошо написанное объяснение.
да отличное и отличное объяснение. но почему в столбце b значения не в порядке? т.е. это 6,5, а не 5,6?
@Ameer, спасибо. Присоединение не гарантирует заказ, вам нужно будет добавить предложение ORDER BY.
Томас: На самом деле, вы и Марк ошиблись насчет другой части формулировки. «Внешние части диаграммы Венна» относятся к «A U B \ A ∩ B». Итак, Марк случайно прямо противоречил самому себе, хотя оставшаяся часть его объяснения, очевидно, была достаточно ясной, чтобы компенсировать это.
Сказать, что внешнее соединение является союз, может показаться немного запутанным, если в результирующем наборе A left outer join B нет несовпадающих элементов B. Не так ли?
«Предполагая, что вы присоединяетесь к столбцам без дубликатов, что является очень частым случаем:» - Сильно ли меняется, когда это не так?
Соединение не дает вам объединения или пересечения чего-либо. Это дает вам замыкание в решетке.
Синтаксис + никогда не был ANSI, это был Oracle, и он всегда был неадекватным для выражений, использующих несколько таблиц или сравнений. Синтаксис ON - ANSI. PS Сравнение с диаграммами Венна сформулировано неправильно. См. Мой комментарий к вопросу.
Вот правильное утверждение для пересечения / объединения круги / наборы 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). См. Мой комментарий (первый) к вопросу.
@HelenNeely К сожалению, это объяснение неверно. Его маркеры верны только тогда, когда все столбцы одинаковы, а язык нечеткий. Смотрите мой комментарий непосредственно перед вашим и мой комментарий по вопросу.
@Damian да, OUTER JOIN и FULL OUTER JOIN эквивалентны, а LEFT / RIGHT JOIN эквивалентны LEFT / RIGHT OUTER JOIN, так же, как INNER JOIN эквивалентно простому JOIN
Я проголосовал против, потому что это неправильно. Пожалуйста, подумайте об удалении ответа, так как он введет в заблуждение поколения студентов, изучающих информатику, которых обманывает большое количество студентов. Диаграммы Венна не объясняют соединение. Внутренняя часть соединения не является пересечением.
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 Этот ответ неясен относительно строк на входе и выходе. Он путает «в левой / правой таблице» с «имеет левую / правую часть в левой / правой» и использует «совпадающую строку» против «все» для обозначения строки, расширенной строкой из другой таблицы против нулей.
Я не вижу много подробностей о производительности и оптимизаторе в других ответах.
Иногда полезно знать, что только INNER JOIN является ассоциативным, что означает, что оптимизатор имеет больше возможностей поиграть с ним. Он может изменить порядок соединения, чтобы ускорить его и сохранить тот же результат. Оптимизатор может использовать большинство режимов соединения.
Как правило, рекомендуется использовать INNER JOIN вместо других типов соединений. (Конечно, если это возможно с учетом ожидаемого набора результатов.)
Вот несколько хороших примеров и объяснений этого странного ассоциативного поведения:
Наверное, не может быть хорошей практикой использовать один тип соединения вместо другого. От того, какое соединение вы используете, зависит, какие данные вы хотите использовать. Если вы используете другой, вы ошибаетесь. К тому же, в Oracle, по крайней мере, этот ответ совершенно неверен. Это звучит совершенно неправильно, и у вас нет доказательств. У тебя есть доказательства?
1. Я имею ввиду пытаться использовать. Я видел, как много людей используют соединения LEFT OUTER повсюду без какой-либо уважительной причины. (Объединенные столбцы были «не нулевыми».) В таких случаях определенно было бы лучше использовать ВНУТРЕННИЕ объединения. 2. Я добавил ссылку, объясняющую неассоциативное поведение лучше, чем я мог бы.
Насколько я знаю, INNER JOIN в большинстве случаев медленнее, чем LEFT JOIN, и люди могут использовать LEFT JOIN вместо INNER JOIN, добавив WHERE для удаления неожиданных результатов NULL;).
Эти комментарии заставили меня немного сомневаться. Как вы думаете, почему INNER медленнее?
Зависит от двигателя. gnu join, joinkeys, DB2, MySQL. Существует множество ловушек производительности, таких как нечеткая типизация или явное приведение типов.
Получить только совпавшие строки, то есть 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
Как называется инструмент? Я нахожу это интересным, так как показывает количество строк и диаграмм Венна.
@GrijeshChauhan Да, но вы можете попробовать запустить его с помощью вино.
Ох! да я .. я использовал SQLyog с вином .. есть еще PlayOnLinux
Ваш текст нечеткий и неправильный. «Только совпавшие строки» - это строки из перекрестного соединения A и B, и то, что извлекается (внутреннее соединение B), не является пересечением A B, а (A левое соединение B) пересекает (A правое соединение B). «Выбранные» строки взяты не из A и B, они из A перекрестного соединения B и из расширенных нулем значений строк из A и B.
@ TusharGupta-curioustushar вам следует включить «Таблицы, используемые для примеров SQL»
«Получить только совпавшие строки, то есть A пересекает B.» Это не правильно.
Внутреннее соединение.
Соединение объединяет строки из двух таблиц. внутреннее соединение пытается сопоставить две таблицы на основе критериев, указанных в запросе, и возвращает только совпадающие строки. Если строка из первой таблицы в объединении соответствует двум строкам во второй таблице, то в результатах будут возвращены две строки. Если в первой таблице есть строка, не соответствующая строке во второй, она не возвращается; аналогично, если есть строка во второй таблице, которая не соответствует строке в первой, она не возвращается.
Внешнее соединение.
оставил присоединиться пытается найти совпадение строк из первой таблицы со строками во второй таблице. Если совпадение не найдено, оно вернет столбцы из первой таблицы и оставит столбцы из второй таблицы пустыми (пустыми).
Присоединяется используются для объединения данных из двух таблиц, в результате чего получается новая временная таблица. Соединения выполняются на основе того, что называется предикатом, который определяет условие, используемое для выполнения соединения. Разница между внутренним соединением и внешним соединением заключается в том, что внутреннее соединение будет возвращать только те строки, которые фактически совпадают на основе предиката соединения. Например, давайте рассмотрим таблицу сотрудников и местоположений:

Внутреннее соединение:- Внутреннее соединение создает новую таблицу результатов путем объединения значений столбцов двух таблиц (Наемный рабочий и Место расположения) на основе предиката соединения. Запрос сравнивает каждую строку Наемный рабочий с каждой строкой Место расположения, чтобы найти все пары строк, которые удовлетворяют предикату соединения. Когда предикат соединения удовлетворяется путем сопоставления значений, отличных от 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 - Синтаксис соединения
лучший ответ на данный момент, альтернативный синтаксис - это то, что я искал, спасибо!
Диаграммы Венна помечены неправильно. Смотрите мои комментарии к вопросу и другие ответы. Также большая часть этого языка бедна. Например: «Когда предикат соединения удовлетворяется путем сопоставления значений, отличных от NULL, значения столбцов для каждой сопоставленной пары строк Employee и Location объединяются в строку результатов». Нет, не «Когда удовлетворяется предикат соединения путем сопоставления значений, отличных от NULL». Значения в строках не имеют значения, кроме того, является ли условие в целом истинным или ложным. Некоторые значения вполне могут быть NULL для истинного условия.
Пожалуйста, используйте текст, а не изображения / ссылки, для текста, включая таблицы и ERD. Используйте изображения только для того, что не может быть выражено в виде текста или для дополнения текста. Изображения нельзя искать, вырезать и вставлять. Включите легенду / ключ и объяснение с изображением.
Простыми словами:
Внутреннее соединение -> Возьмите ТОЛЬКО общие записи из родительской и дочерней таблиц, ГДЕ первичный ключ родительской таблицы совпадает с внешним ключом в дочерней таблице.
Левое присоединение ->
псевдокод
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 как результат соединения.
Пример :

Предположим теперь для 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;
Схематично это выглядит так:

Результат не имеет ничего общего (как такового) с первичными / уникальными / кандидатными ключами и внешними ключами. Бавиур можно и нужно описывать без ссылки на них. Вычисляется перекрестное соединение, затем строки, не соответствующие условию ON, отфильтровываются; дополнительно для внешних объединений строки отфильтрованные / несовпадающие строки расширяются на NULL (на LEFT / RIGHT / FULL и включены.
Предположение, что соединения SQL всегда совпадают по первичным / внешним ключам, приводит к неправильному использованию диаграмм Венна. Пожалуйста, измените свой ответ соответствующим образом.
Ответ заключается в значении каждого из них, поэтому в результатах.
Note :
InSQLitethere is noRIGHT OUTER JOINorFULL OUTER JOIN.
And also inMySQLthere is noFULL 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.
Раскритиковав столь любимую диаграмму Венна, закрашенную красным, я счел справедливым опубликовать свою собственную попытку.
Хотя ответ @Martin Smith во многом является лучшим из этой группы, он показывает только ключевой столбец из каждой таблицы, тогда как я думаю, что в идеале также должны отображаться неключевые столбцы.
Лучшее, что я мог сделать за отведенные полчаса, я все еще не думаю, что это адекватно показывает, что есть нули из-за отсутствия ключевых значений в TableB или что OUTER JOIN на самом деле является объединением, а не объединением:
Вопрос спрашивает разницу между ВНУТРЕННИМ и ВНЕШНИМ объединениями, хотя не обязательно левое внешнее соединение lol
@LearnByReading: мое изображение справа - это правое внешнее соединение, т.е. заменить TableA a LEFT OUTER JOIN TableB b на TableB B RIGHT OUTER JOIN TableA a
Внутреннее соединение - внутреннее соединение с использованием любого из эквивалентных запросов дает пересечение двух столы, то есть двух общих строк.
Левое внешнее соединение - левое внешнее соединение предоставит все строки в A плюс любые общие строки в B.
Полное внешнее соединение - A полное внешнее соединение даст вам объединение A и B, то есть все строки в A и все строки в B. Если что-то в A не имеет соответствующей базы данных в B, тогда часть B равна нулю, и наоборот. наоборот
Это и неправильно, и непонятно. Соединение - это нет пересечение, если в таблицах нет одинаковых столбцов. Внешние соединения не содержат строк из A или B, если они не имеют одинаковых столбцов, и в этом случае не добавляются нули. Вы пытаетесь что-то сказать, но не говорите этого. Вы не объясняете правильно или ясно.
@philipxy: Не согласен с вашим утверждением Join is not an intersection unless the tables have the same columns Нет. Вы можете объединить любые столбцы, которые хотите, и если значение совпадет, они будут объединены.
Этот комментарий столь же неясен, как и ваш ответ. (Я полагаю, вы могли подумать что-то вроде того, что набор значений вложенных строк для общих столбцов результата является пересечением наборов значений вложенных строк для общих столбцов каждого из входов; но это не то, что вы написали. непонятны.)
Я имел в виду, что соединение - это только пересечение входов, когда это естественное внутреннее соединение входов с одними и теми же столбцами. Вы неправильно используете слова «пересечение» и «союз».
Простейшие определения
Внутреннее соединение: возвращает совпадающие записи из обеих таблиц.
Полное внешнее соединение: возвращает сопоставленные и непревзойденные рекорды из обеих таблиц с нулевым значением для несовпадающих записей из Обе таблицы.
Левое внешнее соединение: возвращает совпадающие и несопоставленные записи только из таблицы на Левая сторона.
Правое внешнее соединение: возвращает совпадающие и несопоставленные записи только из таблицы на Правая сторона.
Короче
Совпадение + Несовпадение влево + Несопоставление вправо = Полное внешнее соединение
Совпадение + Несовпадение влево = Левое внешнее соединение
Совпадение + Несовпад справа = Правое внешнее соединение
Соответствует = Внутреннее соединение
Это замечательно и объясняет, почему соединение не работает должным образом для индексов временных рядов. Отметки времени с интервалом в одну секунду не имеют себе равных.
@yeliabsalohcin Вы не объясняете «как ожидалось» здесь или «работает» в своем комментарии к вопросу. Это просто какое-то необъяснимое личное заблуждение, которого вы странно ожидаете от других. Если вы относитесь к словам так же небрежно, когда читаете - неверно истолковываете четкое письмо и / или принимаете нечеткое письмо - как когда вы пишете здесь, то вы можете ожидать неправильных представлений. На самом деле этот ответ, как и большинство здесь, неясен и неверен. «Внутреннее объединение: возвращает совпадающие записи из обеих таблиц» неверно, если наборы входных столбцов различаются. Это пытающийся, чтобы сказать что-то определенное, но это не. (См. Мой ответ.)
Проще говоря,
1.ВНУТРЕННЕЕ СОЕДИНЕНИЕ ИЛИ ЭКВИ СОЕДИНЕНИЕ: Возвращает набор результатов, который соответствует только условию в обеих таблицах.
2.ВНЕШНЕЕ СОЕДИНЕНИЕ: Возвращает набор результатов всех значений из обеих таблиц, даже если есть соответствие условий или нет.
3.ЛЕВАЯ ПРИСОЕДИНИТЬСЯ: Возвращает набор результатов всех значений из левой таблицы и только строк, которые соответствуют условию в правой таблице.
4.ПРАВО ПРИСОЕДИНИТЬСЯ: Возвращает набор результатов всех значений из правой таблицы и только строк, которые соответствуют условию в левой таблице.
5.ПОЛНОЕ СОЕДИНЕНИЕ: Полное соединение и полное внешнее соединение - это одно и то же.
Точный алгоритм для 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) для ЛЕВОГО внешнего соединения или (Null, b) для ПРАВОГО внешнего соединения. Это необходимо для того, чтобы в окончательных результатах присутствовали все строки первой таблицы.Примечание: условие, указанное в предложении ON, может быть любым, не требуется использовать Первичные ключи (и вам не нужно всегда ссылаться на столбцы из обеих таблиц)! Например:
... ON T1.title = T2.title AND T1.version < T2.version (=> см. Этот пост как пример использования: Выбирать только строки с максимальным значением в столбце)... ON T1.y IS NULL... ON 1 = 0 (как образец)Примечание: Левое соединение = левое внешнее соединение, правое соединение = правое внешнее соединение.
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.Правое внешнее соединение: Также называется правым соединением. Он возвращает совпадающие строки из левой таблицы (если есть) и все строки, присутствующие в правой таблице.
Преимущества объединений
Это правильно, только если в таблицах есть одинаковый набор столбцов. (Это путает внутреннее соединение с пересечением, а полное соединение - с объединением.) Также "совпадение" не определено. Прочтите мои другие комментарии.
По этой теме много дезинформации, в том числе здесь, в 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
Это также объясняет, почему (-подобные) диаграммы Венна бесполезны для внутреннего и внешнего соединения.
Подробнее о том, почему диаграммы Венна (-подобные) не полезны для объединений:
Диаграмма Венна для естественного соединения
Я действительно прочитал много ваших комментариев. Когда вы говорите, что «диаграмма Венна при правильной интерпретации может представлять внутреннее и внешнее соединение», вы имеете в виду, когда ее правильно интерпретирует наблюдатель или сама диаграмма Венна? Если второе, нарисуйте его :)
Я не уверен, что вы пытаетесь сказать. Я говорю о стандартной интерпретации диаграммы Венна как набора элементов. (Потому что некоторые виды использования диаграмм даже не справляются с этим.) «Правильно» для приложения включает в себя указание, что такое наборы и / или элементы. См. Комментарий вверху этой страницы с 50 голосами за диаграмму Венна для внутренних и внешних соединений. Я отредактирую некоторые свои комментарии к этому вопросу. Мне не нужна диаграмма Венна в этом посте.
Я тоже не хочу диаграмм Венна!
Я должен признать, что, несмотря на мои быстрые формулировки в комментариях, поскольку SQL включает в себя пакеты и нули, а культура SQL не имеет общей терминологии для обозначения и различения соответствующих понятий, нетривиально даже четко объяснить, как элементы диаграммы Венна 1: 1 с выходными «строками», не говоря уже о входных «строках». Или что делают внутренние или внешние соединения, не говоря уже об их различии. "value" может включать или не включать NULL, "row" может быть списком значений по сравнению с слотом в значении таблицы или переменная & "=" может быть SQL "=" с равенством.
Подобно нашему обсуждению декартовых продуктов и реляционных продуктов, я подозреваю, что это тот случай, когда диаграммы Венна имеют большой смысл для людей, которые уже понимают различия между типами соединений!
В случае «реляционного декартова произведения» это стандартное и разумное название для определенной вещи, которую люди обычно понимают и которая обоснованно описывается как похожая на декартово произведение. В случае диаграмм Венна SQL они не имеют смысла, люди просто предполагают, что они есть, независимо от того, понимают ли они операторы / различия.
Разница между inner join и outer join заключается в следующем:
Inner join - это соединение, которое объединяет таблицы на основе совпадающих кортежей, тогда как outer join - это соединение, которое объединяет таблицу на основе как совпавших, так и несопоставленных кортежей.Inner join объединяет совпавшие строки из двух таблиц, в которых несопоставленные строки опущены, тогда как outer join объединяет строки из двух таблиц, и несогласованные строки заполняются нулевым значением.Inner join похож на операцию пересечения, тогда как outer join похож на операцию объединения.Inner join бывает двух типов, а outer join - трех типов.outer join быстрее, чем inner join.Результат внешнего соединения такой же, как и при внутреннем соединении, но плюс несколько дополнительных строк, поэтому я понятия не имею, почему вы думаете, что внешнее соединение будет быстрее. И что это за «два типа» внутреннего соединения? Я полагаю, вы имеете в виду полное, левое и правое внешнее?
Внешнее соединение не быстрее внутреннего.
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.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, которые вы ищете МОГ БЫ или МОЖЕТ НЕ, существуют для каждого проекта базы данных.Примеры
Предположим, у вас есть две таблицы с одним столбцом в каждой и следующие данные:
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
Это соединение возвращает все строки таблицы с левой стороны соединения и соответствующие строки для таблицы с правой стороны соединения. Строки, для которых нет соответствующей строки с правой стороны, набор результатов будет содержать null. 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
Диаграмм Венна недостаточно для описания SQL-соединений в общем случае. Соединения SQL не обязательно должны соответствовать строкам между таблицами один к одному, например использование внешнего ключа по сравнению с первичным ключом.
Как соединить 2 таблицы без совпадения строки? Вам понадобится первичный или внешний ключ столбца или какое-то общее поле, чтобы вы могли выполнить соединение. Мне интересно, почему вы проголосовали против этого ответа. И диаграмма Венна является источником, объясняющим, как работает SQL JOIN. У вас есть лучшие примеры для представления объединений? Если нет, проголосуйте за него, чтобы люди получили лучшие решения. Спасибо.
Вы тот, кто размещает диаграммы в посте. Какая легенда к схемам? - Каковы элементы каждого набора? А как насчет того, что столы - это сумки, а не наборы? Вы не говорите. Одна вещь, которой они не являются, - это ряды A и B на этикетках. Смотрите мои комментарии к сообщениям на этой странице. Этот пост просто слепо повторяет неправильное использование, которое видели в другом месте, но не поняли или не подвергли сомнению. Также то, что вы говорите здесь в тексте, непонятно и неверно. Кроме того, это ничего не добавляет ко многим уже здесь ответам. (Несмотря на то, что почти все они довольно плохие.) PS Уточняйте, пожалуйста, правки, а не комментарии.
FK не нужны для присоединения или запроса. Любые 2 таблицы могут быть объединены при любом условии, включающем их столбцы, и независимо от каких-либо ограничений, триггеров или утверждений.
Объединения легче объяснить на примере:
Чтобы смоделировать людей и электронные письма, хранящиеся в отдельных таблицах,
Таблица A и Таблица B объединены Table_A.я бы = Table_B.name_id
Внутреннее соединение
Отображаются только строки с совпадающими идентификаторами.
Внешние соединения
Отображаются совпадающие идентификаторы и несоответствующие строки для Таблица А.
Отображаются совпадающие идентификаторы и несоответствующие строки для Таблица B.
Отображаются совпадающие идентификаторы и несовпадающие строки из обеих таблиц.
Примечание: полное внешнее соединение недоступно в MySQL.
Из ответов, комментариев и ссылок на них ниже только один фактически объясняет, как диаграммы Венна представляют операторы: Область пересечения круга представляет набор строк в A JOIN B. Область, уникальная для каждого круга, представляет набор строк, которые вы получаете, беря его таблицу строки, которые не участвуют в A JOIN B, и добавление столбцов, уникальных для другой таблицы, имеют значение NULL. (И большинство дает смутное фиктивное соответствие кружков A и B.)