В чем разница между "INNER JOIN" и "OUTER JOIN"?
Также как сделать LEFT JOIN
, RIGHT JOIN
а также FULL JOIN
вписаться?
41 ответ
Предполагается, что вы объединяете столбцы без дубликатов, что является очень распространенным случаем:
Внутреннее соединение 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
Также вы можете рассмотреть следующую схему для разных типов соединений;
Источник: визуальное представление SQL-соединений, подробно объясняемое CL Моффатом.
Диаграммы Венна на самом деле не делают это для меня.
Например, они не показывают какого-либо различия между перекрестным соединением и внутренним объединением или, в более общем случае, показывают какое-либо различие между различными типами предикатов объединения или предоставляют основу для рассуждений о том, как они будут работать.
Нет никакой замены для понимания логической обработки, и это все равно довольно просто понять.
- Представьте себе перекрестное соединение.
- Оценить
on
предложение для всех строк из шага 1, сохраняя те, где предикат оценивает вtrue
- (Только для внешних объединений) добавьте обратно во все внешние строки, которые были потеряны на шаге 2.
(Примечание: на практике оптимизатор запросов может найти более эффективные способы выполнения запроса, чем приведенное выше чисто логическое описание, но конечный результат должен быть таким же)
Я начну с анимированной версии полного внешнего соединения. Дальнейшее объяснение следует.
объяснение
Исходные таблицы
Сначала начните с CROSS JOIN
(AKA декартово произведение). Это не имеет ON
предложение и просто возвращает каждую комбинацию строк из двух таблиц.
ВЫБЕРИТЕ А.ЦВЕТ, Б.ЦВЕТ ИЗ КРЕСТА СОЕДИНИТЕ B
Внутренние и внешние объединения имеют предикат предложения ON.
- Внутреннее соединение. Оцените условие в предложении "ON" для всех строк в результате перекрестного соединения. Если true, вернуть объединенную строку. В противном случае откажитесь от него.
- Оставил Внешнее Соединение. То же, что и для внутреннего соединения, для любых строк в левой таблице, которые не совпадают ни с чем, выведите их со значениями NULL для правых столбцов таблицы.
- Право Внешнее Соединение. То же, что и для внутреннего соединения, для любых строк в правой таблице, которые не совпадают ни с чем, выведите их со значениями NULL для левых столбцов таблицы.
- Полное внешнее соединение. То же, что и для внутреннего соединения, затем сохраняются левые несопоставленные строки, как в левом внешнем соединении, и правые несоответствующие строки в соответствии с правым внешним соединением
Некоторые примеры
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour
Выше классическое равное соединение.
Анимированная версия
ВЫБРАТЬ A.Colour, B.Colour ОТ ВНУТРЕННЕГО СОЕДИНЕНИЯ B НА A.Colour NOT IN ("Зеленый", "Синий")
Условие внутреннего соединения не обязательно должно быть условием равенства и не должно ссылаться на столбцы обеих (или даже обеих) таблиц. Оценка A.Colour NOT IN ('Green','Blue')
на каждом ряду перекрестного соединения возвращается.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ВНУТРЕННЕГО СОЕДИНЕНИЯ B ON 1 =1
Условие соединения оценивается как true для всех строк в результате перекрестного соединения, так что это то же самое, что и перекрестное соединение. Я не буду повторять картину 16 строк снова.
ВЫБРАТЬ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour
Внешние объединения логически оцениваются так же, как и внутренние соединения, за исключением того, что если строка из левой таблицы (для левого объединения) вообще не объединяется ни с одной строкой из правой таблицы, она сохраняется в результате с NULL
значения для правых столбцов.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour ГДЕ B.Colour is NULL
Это просто ограничивает предыдущий результат, возвращая только те строки, где B.Colour IS NULL
, В этом конкретном случае это будут строки, которые были сохранены, так как они не совпадали в правой таблице, и запрос возвращает одну красную строку, не сопоставленную в таблице. B
, Это известно как анти-полусоединение.
Важно выбрать столбец для IS NULL
тест, который либо не обнуляется, либо для которого условие соединения гарантирует, что любой NULL
значения будут исключены, чтобы этот шаблон работал правильно и избегал просто возвращать строки, которые имеют NULL
значение для этого столбца в дополнение к несоответствующим строкам.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ПРАВИЛЬНОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour
Правые внешние объединения действуют аналогично левым внешним соединениям, за исключением того, что они сохраняют несоответствующие строки из правой таблицы и нулевые расширяют левые столбцы.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ПОЛНОГО НАРУЖНОГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour
Полные внешние объединения объединяют поведение левого и правого объединений и сохраняют несовпадающие строки из левой и правой таблиц.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ПОЛНОГО НАРУЖНОГО СОЕДИНЕНИЯ B ON 1 = 0
Строки в перекрестном соединении не соответствуют 1=0
сказуемое. Все строки с обеих сторон сохраняются с использованием обычных правил внешнего соединения с NULL в столбцах таблицы на другой стороне.
ВЫБЕРИТЕ COALESCE(A.Colour, B.Colour) КАК ЦВЕТ ИЗ ПОЛНОГО НАРУЖНОГО СОЕДИНЕНИЯ B ON 1 = 0
С небольшой поправкой к предыдущему запросу можно смоделировать UNION ALL
из двух таблиц.
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour ГДЕ B.Colour = 'Green'
Обратите внимание, что WHERE
Предложение (если присутствует) логически выполняется после объединения. Одной из распространенных ошибок является выполнение левого внешнего соединения, а затем включение предложения WHERE с условием в правой таблице, которое заканчивается исключением несовпадающих строк. Вышеуказанное завершает выполнение внешнего соединения...
... А затем выполняется предложение "Где". NULL= 'Green'
не оценивается как истина, поэтому строка, сохраненная внешним соединением, в итоге отбрасывается (вместе с синим), эффективно преобразовывая соединение обратно во внутреннее.
Если бы целью было включить только строки из B, где Color - зеленый, и все строки из A независимо от правильного синтаксиса были бы
ВЫБЕРИТЕ A.Colour, B.Colour ИЗ ЛЕВОГО ВНЕШНЕГО СОЕДИНЕНИЯ B НА A.Colour = B.Colour AND B.Colour = 'Green'
SQL Fiddle
Посмотрите эти примеры в прямом эфире на SQLFiddle.com.
Я рекомендую статью в блоге Джеффа. Лучшее описание, которое я когда-либо видел, плюс есть визуализация, например:
Внутреннее соединение:
Полное внешнее присоединение:
Следующее было взято из статьи " MySQL - левое и правое соединение, внутреннее соединение и внешнее соединение" Грэма Эллиса в его блоге Horse's Mouth.
В базе данных, такой как MySQL, данные делятся на несколько таблиц, которые затем соединяются (Joined
) вместе JOIN
в SELECT
Команды для чтения записей из нескольких таблиц. Прочитайте этот пример, чтобы увидеть, как это работает.
Сначала несколько примеров данных:
people
mysql> select * from people;
+------------+--------------+------+
| name | phone | pid |
+------------+--------------+------+
| Mr Brown | 01225 708225 | 1 |
| Miss Smith | 01225 899360 | 2 |
| Mr Pullen | 01380 724040 | 3 |
+------------+--------------+------+
3 rows in set (0.00 sec)
property
mysql> select * from property;
+------+------+----------------------+
| pid | spid | selling |
+------+------+----------------------+
| 1 | 1 | Old House Farm |
| 3 | 2 | The Willows |
| 3 | 3 | Tall Trees |
| 3 | 4 | The Melksham Florist |
| 4 | 5 | Dun Roamin |
+------+------+----------------------+
5 rows in set (0.00 sec)
РЕГУЛЯРНОЕ СОЕДИНЕНИЕ
Если мы выполняем обычное JOIN (без ключевых слов INNER, OUTER, LEFT или RIGHT), то мы получаем все записи, которые соответствующим образом совпадают в двух таблицах, а записи в обеих входящих таблицах, которые не совпадают, не сообщаются:
mysql> select name, phone, selling
from people join property
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+-----------+--------------+----------------------+
4 rows in set (0.01 sec)
ЛЕВЫЙ РЕЙТИНГ
Если мы выполняем LEFT JOIN, мы получаем все записи, которые совпадают одинаково, и IN ADDITION мы получаем дополнительную запись для каждой несопоставленной записи в левой таблице соединения - таким образом, гарантируя (в этом примере), что каждый ЛИЦО получает упоминание:
mysql> select name, phone, selling
from people left join property
on people.pid = property.pid;
+------------+--------------+----------------------+
| name | phone | selling |
+------------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Miss Smith | 01225 899360 | NULL <<-- unmatch |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
+------------+--------------+----------------------+
5 rows in set (0.00 sec)
ПРАВИЛЬНОЕ СОЕДИНЕНИЕ
Если мы выполняем ПРАВИЛЬНОЕ СОЕДИНЕНИЕ, мы получаем все соответствующие записи и В ДОПОЛНЕНИИ дополнительную запись для каждой несопоставленной записи в правой таблице объединения - в моем примере это означает, что каждое свойство получает упоминание, даже если мы этого не делаем есть данные продавца:
mysql> select name, phone, selling
from people right join property
on people.pid = property.pid;
+-----------+--------------+----------------------+
| name | phone | selling |
+-----------+--------------+----------------------+
| Mr Brown | 01225 708225 | Old House Farm |
| Mr Pullen | 01380 724040 | The Willows |
| Mr Pullen | 01380 724040 | Tall Trees |
| Mr Pullen | 01380 724040 | The Melksham Florist |
| NULL | NULL | Dun Roamin |
+-----------+--------------+----------------------+
5 rows in set (0.00 sec)
INNER JOIN выполняет полное объединение, как и в первом примере, и слово OUTER может быть добавлено после слова LEFT или RIGHT в последних двух примерах - оно предусмотрено для совместимости с ODBC и не добавляет дополнительных возможностей.
Объединения используются для объединения данных из двух таблиц, в результате чего получается новая временная таблица. Объединения выполняются на основе чего-то, называемого предикатом, в котором указывается условие, используемое для выполнения объединения. Разница между внутренним соединением и внешним соединением заключается в том, что внутреннее объединение будет возвращать только те строки, которые действительно совпадают, основываясь на предикате соединения. Давайте рассмотрим таблицу Employee и 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".
заказы
- Номер заказа
- Имя покупателя
Информация для заказа
- 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
,
Простыми словами:
Внутреннее соединение -> Возьмите ТОЛЬКО общие записи из родительской и дочерней таблиц, ГДЕ первичный ключ родительской таблицы соответствует внешнему ключу в дочерней таблице.
Осталось присоединиться ->
псевдокод
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
возвращает все строки из второй таблицы, даже если в первой таблице нет совпадений.
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 / НАРУЖНОЕ СОЕДИНЕНИЕ:
Вы можете иметь все эти данные таблиц с 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 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
Ну, так как вам нужно, вы выбираете каждый, который покрывает ваши потребности;).
Это хорошее схематичное объяснение для всех видов соединений
источник: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
Внутреннее соединение.
Объединение объединяет строки из двух таблиц. Внутреннее объединение пытается сопоставить две таблицы на основе критериев, указанных в запросе, и возвращает только те строки, которые соответствуют. Если строка из первой таблицы в соединении совпадает с двумя строками во второй таблице, то в результатах будут возвращены две строки. Если в первой таблице есть строка, которая не соответствует строке во второй таблице, она не возвращается; аналогично, если во второй таблице есть строка, которая не соответствует строке в первой, она не возвращается.
Внешнее соединение.
Левое объединение пытается найти соответствие строк из первой таблицы и строк во второй таблице. Если он не может найти совпадение, он вернет столбцы из первой таблицы и оставит столбцы из второй таблицы пустыми (пустыми).
INNER JOIN
наиболее типичное объединение для двух или более таблиц. Возвращает совпадение данных как для таблицы ON primarykey, так и для отношения forignkey.OUTER JOIN
такой же какINNER JOIN
, но это также включаетNULL
данные по ResultSet.LEFT JOIN
знак равноINNER JOIN
+ Несоответствующие данные левой таблицы с нулевым соответствием в правой таблице.RIGHT JOIN
знак равноINNER JOIN
+ Несоответствующие данные правой таблицы с нулевым соответствием на левой таблице.FULL JOIN
знак равноINNER JOIN
+ Несоответствующие данные в правой и левой таблицах с нулевыми совпадениями.
- Самостоятельное объединение не является ключевым словом в 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
Я не вижу подробностей о производительности и оптимизаторе в других ответах.
Иногда полезно знать, что только INNER JOIN
является ассоциативным, что означает, что оптимизатор имеет больше возможностей для игры с ним. Он может изменить порядок соединения, чтобы сделать его быстрее, сохраняя тот же результат. Оптимизатор может использовать большинство режимов соединения.
Как правило, это хорошая практика, чтобы попытаться использовать INNER JOIN
вместо разного рода соединений. (Конечно, если это возможно, учитывая ожидаемый набор результатов.)
Здесь есть несколько хороших примеров и объяснений об этом странном ассоциативном поведении:
Общая идея
Пожалуйста, смотрите ответ на Martin Smith за лучшие illustations и объяснения различных соединений, в том числе и в особенности различия междуFULL OUTER JOIN
, RIGHT OUTER JOIN
а также LEFT OUTER JOIN
.
Эти две таблицы образуют основу для представления JOIN
s ниже:
КРЕСТНОЕ СОЕДИНЕНИЕ
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
а также WHERE
КРЕСТНОЕ СОЕДИНЕНИЕ
CROSS 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
становится декартовым произведением. Это то же самое, что и The General Idea /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
table) в обсуждении ниже.
КРЕСТНОЕ СОЕДИНЕНИЕ
Каждый элемент в обоих наборах соответствует каждому элементу в другом наборе, что означает, что нам нужно A
количество каждого B
элементы и B
количество каждого A
элементы, чтобы правильно представить это декартово произведение. Теория множеств не предназначена для множества идентичных элементов в наборе, поэтому я считаю, что диаграммы Венна, чтобы правильно представить это, непрактично / невозможно. Не кажется, чтоUNION
подходит вообще.
Ряды четкие. ВUNION
всего 7 рядов. Но они несовместимы для общегоSQL
набор результатов. И это не такCROSS JOIN
вообще работает:
Пытаемся изобразить это так:
..но сейчас это выглядит как INTERSECTION
, что, конечно, не так. Кроме того, вINTERSECTION
это фактически в любом из двух различных наборов. Однако это очень похоже на результаты поиска, подобные этому:
Для справки один доступный для поиска результат для CROSS JOIN
s можно увидеть на Tutorialgateway. ВINTERSECTION
, как и этот, пусто.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
Значение элемента зависит от JOIN
состояние. Это можно представить при условии, что каждая строка становится уникальной для этого условия. Имея в видуid=x
верно только для одной строки. Однажды строка в таблицеA
(citizen
) соответствует нескольким строкам в таблице B
(postalcode
) под JOIN
состояние, результат имеет те же проблемы, что и CROSS JOIN
: Строка должна быть представлена несколько раз, и теория множеств не предназначена для этого. При условии уникальности, диаграмма может работать, но учтите, чтоJOIN
Условие определяет размещение элемента на диаграмме. Глядя только на значенияJOIN
состояние с остальной частью ряда только для езды:
Это представление полностью разваливается при использовании INNER JOIN
с ON 1 = 1
состояние превращает его в CROSS JOIN
.
С самообслуживаниемJOIN
, строки фактически являются идентичными элементами в обеих таблицах, но представляют таблицы как A
а также B
не очень подходит. Например, обычное само-JOIN
условие, которое делает элемент в A
чтобы соответствовать другому элементу в B,ON A.parent = B.child
, делая матч из A
к B
на отдельные элементы. Из примеров, которые были быSQL
как это:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
Meaning Smith is the leader of both Green and Jensen.
OUTER JOIN
Again the troubles begin when one row has multiple matches to rows in the other table. This is further complicated because the OUTER JOIN
can be though of as to match the empty set. But in set theory the union of any set C
and an empty set, is always just C
. The empty set adds nothing. The representation of this LEFT OUTER JOIN
is usually just showing all of A
to illustrate that rows in A
are selected regardless of whether there is a match or not from B
. The "matching elements" however has the same problems as the illustration above. They depend on the condition. And the empty set seems to have wandered over to A
:
WHERE clause - making sense
Finding all rows from a CROSS JOIN
with Smith and postalcode on the Moon:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
Now the Venn diagram isn't used to reflect the JOIN
. It's used only for the WHERE
clause:
..and that makes sense.
When INTERSECT and UNION makes sense
INTERSECT
As explained an INNER JOIN
is not really an INTERSECT
. However INTERSECT
s can be used on results of seperate queries. Here a Venn diagram makes sense, because the elements from the seperate queries are in fact rows that either belonging to just one of the results or both. Intersect will obviously only return results where the row is present in both queries. This SQL
will result in the same row as the one above WHERE
, and the Venn diagram will also be the same:
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';
UNION
An OUTER JOIN
is not a UNION
. However UNION
work under the same conditions as INTERSECT
, resulting in a return of all results combining both SELECT
s:
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';
which is equivalent to:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
..and gives the result:
Also here a Venn diagram makes sense:
When it doesn't apply
Важное замечание: они работают, только если структура результатов двух SELECT одинакова, что позволяет проводить сравнение или объединение. Результаты этих двух не позволят:
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
..пытаться объединить результаты с UNION
дает
ORA-01790: expression must have same datatype as corresponding expression
Для дальнейшего интереса прочтите " Скажите НЕТ диаграммам Венна при объяснении соединений JOIN и sql в виде диаграммы Венна". Оба также покрываютEXCEPT
.
Раскритиковав столь любимую диаграмму Венна в красных тонах, я подумал, что будет справедливо опубликовать мою собственную попытку.
Несмотря на то, что ответ @Martin Smith является лучшим из всей этой группы, он показывает только ключевые столбцы из каждой таблицы, в то время как я считаю, что в идеале также должны быть показаны неключевые столбцы.
Лучшее, что я мог сделать за полчаса, я все еще не думаю, что это адекватно показывает, что нулевые значения есть из-за отсутствия ключевых значений в TableB
или это OUTER JOIN
на самом деле объединение, а не объединение:
Точный алгоритм для 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
(как образец)
Примечание: левое соединение = левое внешнее соединение, правое соединение = правое внешнее соединение.
Разница заключается в способе объединения таблиц, если нет общих записей.
JOIN
такой же какINNER JOIN
и означает показывать только записи, общие для обеих таблиц. Распространены ли записи, определяется полями в предложении соединения. Например:FROM t1 JOIN t2 on t1.ID = t2.ID
значит показывать только записи где одинаковые
ID
значение существует в обеих таблицах.LEFT JOIN
такой же какLEFT OUTER JOIN
и означает показать все записи из левой таблицы (т. е. ту, которая предшествует в операторе SQL) независимо от наличия соответствующих записей в правой таблице.RIGHT JOIN
такой же какRIGHT OUTER JOIN
и означает противоположностьLEFT JOIN
, т.е. показывает все записи из второй (правой) таблицы и только совпадающие записи из первой (левой) таблицы.
Источник: В чем разница между левым, правым, внутренним, внешним, присоединением?
Простейшие определения
Внутреннее объединение: возвращает сопоставленные записи из обеих таблиц.
Полное внешнее объединение: возвращает сопоставленные и несопоставленные записи из обеих таблиц со значением NULL для несопоставленных записей из обеих таблиц.
Левое внешнее объединение: возвращает сопоставленные и несопоставленные записи только из таблицы на левой стороне.
Правое внешнее объединение: возвращает сопоставленные и несопоставленные записи только из таблицы на правой стороне.
Короче
Совпадение + Несоответствие слева + Несоответствие справа = Полное внешнее соединение
Совпадение + Левое Несоответствие = Левое внешнее соединение
Совпадение + Право Несоответствие = Право Наружное соединение
Matched = Inner Join
Разница заключается в способе объединения таблиц, если нет общих записей.
JOIN
такой же как INNER JOIN
и означает показывать только записи, общие для обеих таблиц. Распространены ли записи, определяется полями в предложении соединения.
Например:
SELECT *
FROM t1
JOIN t2 on t1.ID = t2.ID
Это значит показывать только записи, где одинаковые ID
значение существует в обеих таблицах.
LEFT JOIN
такой же как LEFT OUTER JOIN
и означает показать все записи из левой таблицы (то есть ту, которая предшествует в операторе SQL) независимо от наличия соответствующих записей в правой таблице.
RIGHT JOIN
такой же как RIGHT OUTER JOIN
и означает противоположность LEFT JOIN
, т.е. показывает все записи из второй (правой) таблицы и только совпадающие записи из первой (левой) таблицы.
Внутреннее объединение Внутреннее объединение фокусируется на общности двух таблиц. При использовании внутреннего соединения должны быть хотя бы некоторые совпадающие данные между двумя (или более) сравниваемыми таблицами. Внутреннее объединение ищет в таблицах совпадающие или перекрывающиеся данные. Найдя его, внутреннее объединение объединяет и возвращает информацию в одну новую таблицу.
Внешнее объединение Внешнее объединение возвращает набор записей (или строк), которые включают то, что вернуло бы внутреннее объединение, но также включают другие строки, для которых не найдено соответствующего соответствия в другой таблице.
Существует три типа внешних соединений:
Левое внешнее соединение (или левое соединение) Правое внешнее соединение (или правое соединение) Полное внешнее соединение (или полное соединение) Каждое из этих внешних объединений относится к части данных, которые сравниваются, объединяются и возвращаются. Иногда в этом процессе будут возникать пустые значения, поскольку некоторые данные являются общими, а другие - нет.
Проще говоря,
1. INNER JOIN ИЛИ EQUI JOIN: Возвращает набор результатов, который соответствует только условию в обеих таблицах.
2. ВНЕШНЕЕ СОЕДИНЕНИЕ: Возвращает набор результатов всех значений из обеих таблиц, даже если условие соответствует или нет.
3. LEFT JOIN: возвращает набор результатов всех значений из левой таблицы и только строк, соответствующих условию в правой таблице.
4. RIGHT JOIN: возвращает набор результатов всех значений из правой таблицы и только строк, соответствующих условию в левой таблице.
5. ПОЛНОЕ СОЕДИНЕНИЕ: полное соединение и полное внешнее соединение - это одно и то же.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ
Внутреннее соединение создает результирующий набор, который ограничен строками, в которых есть совпадения в обеих таблицах для того, что мы ищем. Если вы не знаете, какой тип объединения вам нужен, обычно это будет лучшим выбором.
ЛЕВОЕ НАРУЖНОЕ СОЕДИНЕНИЕ
Левое внешнее соединение или левое соединение приводит к набору, в котором сохраняются все строки из первой или левой стороны таблицы. Строки из второй или правой таблицы отображаются только в том случае, если они совпадают со строками из первой таблицы. Там, где есть значения из левой таблицы, но не из правой, таблица будет читать ноль, что означает, что значение не было установлено.
ПРАВО НАРУЖНОЕ СОЕДИНЕНИЕ
Правое внешнее соединение или правое соединение аналогично левому соединению, за исключением того, что роли поменялись местами. Все строки из правой таблицы отображаются в результате, но строки из таблицы слева присутствуют только в том случае, если они соответствуют таблице справа. Пустые пробелы равны нулю, как и при левом соединении.
ПОЛНОЕ НАРУЖНОЕ СОЕДИНЕНИЕ
Полное внешнее соединение или просто внешнее соединение создает набор результатов со всеми строками обеих таблиц, независимо от того, есть ли совпадения. Аналогично левому и правому объединениям, мы называем пустые пространства пустыми.
Для получения дополнительной ссылки
В чем разница между "INNER JOIN" и "OUTER JOIN"?
Это наиболее часто используемые экзистенциальные операторы в SQL, где INNER JOIN
используется для "существует" и LEFT OUTER JOIN
используется для "не существует".
Рассмотрим эти запросы:
users who have posted and have votes
users who have posted but have no badges
Люди, которые ищут решения на основе множеств (отраслевой термин), распознают соответствующие запросы как:
users who have posted INTERSECT users who have votes
users who have posted MINUS users who have badges
Переводя их в стандартный SQL:
SELECT UserId FROM Posts
INTERSECT
SELECT UserId FROM Votes;
SELECT UserId FROM Posts
EXCEPT
SELECT UserId FROM Badges;
Другие будут думать в том же духе:
users who have posted and IN the set of users who have votes
users who have posted and NOT IN the set of users who have badges
Переводя их в стандартный SQL:
SELECT UserId
FROM Posts
WHERE UserId IN ( SELECT UserId FROM Votes );
SELECT UserId
FROM Posts
WHERE UserId NOT IN ( SELECT UserId FROM Badges );
Некоторые будут думать с точки зрения "существования" в наборах, например
users who have posted and EXIST in the set of users who have votes
users who have posted and do NOT EXIST in the set of users who have badges
Переводя их в стандартный SQL (обратите внимание, теперь нам нужно использовать переменные диапазона, т.е. p
, v
, b
):
SELECT p.UserId
FROM Posts p
WHERE EXISTS ( SELECT *
FROM Votes v
WHERE v.UserId = p.UserId );
SELECT p.UserId
FROM Posts p
WHERE NOT EXISTS ( SELECT *
FROM Badges b
WHERE b.UserId = p.UserId );
Тем не менее, я обнаружил, что подход "отраслевого стандарта" заключается исключительно в использовании соединений. Я не знаю, что здесь происходит ( закон инструмента? Преждевременная оптимизация?), Поэтому я сразу перейду к синтаксису:
SELECT p.UserId
FROM Posts p
INNER JOIN Votes v ON v.UserId = p.UserId;
SELECT p.UserId
FROM Posts p
LEFT JOIN Badges b ON b.UserId = p.UserId
WHERE b.UserId IS NULL;
Что следует отметить:
- Единственный прогноз от
Users
но нам все еще нужны все эти переменные диапазона (p
,v
,b
) для условий поиска. UserId IS NULL
условие поиска "принадлежит"OUTER JOIN
но отключен в запросе.LEFT
является отраслевым стандартом: профессионалы перепишут запрос, чтобы избежать использованияRIGHT
!OUTER
ключевое слово изLEFT OUTER JOIN
опущен
Заключительные замечания:
Иногда объединения используются в запросах исключительно для определения того, существуют или не существуют значения в другом наборе. Научитесь внимательно смотреть на проецируемые атрибуты (столбцы в SELECT
предложение): если в объединенной таблице их нет, то они просто используются как экзистенциальные операторы. Дополнительно для внешнего соединения ищите экземпляры <key_column> IS NULL
в WHERE
пункт.
left join on
(ака left outer join on
) возвращает inner join on
строки union all
несопоставленные левые строки таблицы, расширенные нулями.
right join (on
ака right outer join on
) возвращает inner join on
строки union all
несоответствующие правые строки таблицы, расширенные нулями.
full join on
(ака full outer join on
) возвращает inner join on
строки union all
несопоставленные левые строки таблицы, расширенные нулями union all
несоответствующие правые строки таблицы, расширенные нулями.
(SQL Standard 2006 SQL / Foundation 7.7 Синтаксические правила 1, Общие правила 1 b, 3 c & d, 5 b.)
Так что не outer join
пока вы не знаете, что лежит в основе inner join
вовлечен.
Узнайте, какие строки inner join
возвращается.
Прочитайте мои комментарии, есть много запутанных и плохих ответов.
Тогда прочитайте мои комментарии здесь, многие из запутанных и плохих ответов.
В 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 выбирает все строки из обеих таблиц, пока выполняется условие. Это ключевое слово создаст набор результатов путем объединения всех строк из обеих таблиц, которым удовлетворяет условие, т.е. значение общего поля будет одинаковым.
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 aLEFT 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 (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.
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