Самостоятельное объединение в SQL Oracle; Почему правое внешнее объединение не сохраняет все значения таблицы
Я не понимаю, почему правое внешнее соединение (из приведенного ниже примера) не дает полный набор данных таблицы, как левое внешнее соединение; поскольку внешние объединения всегда сохраняют строки соответствующей таблицы.
Создать таблицу
create table join_test
(id number unique not null, name varchar2(10), department varchar2(10));
Заполнить таблицу
select * from join_test;
ID NAME DEPARTMENT 1 stelios sa 2 andros sa 3 stav ba 4 mary ba 5 antonia la 6 lambros ka
Внутреннее соединение
select j1.name, j1.department
from join_test j1 join join_test j2
on(j1.department=j2.department and j1.name<>j2.name);
NAME DEPARTMENT andros sa steliso sa mary ba stav ba
Левое внешнее соединение
select j1.name, j1.department
from join_test j1 left join join_test j2
on(j1.department=j2.department and j1.name<>j2.name)
NAME DEPARTMENT andros sa steliso sa mary ba stav ba antonia la lambros ka
Правое внешнее соединение
select j1.name, j1.department
from join_test j1 right join join_test j2
on(j1.department=j2.department and j1.name<>j2.name)
NAME DEPARTMENT steliso sa andros sa stav ba mary ba
Изменение списка выбора на j2
select j2.name, j2.department
from join_test j1 right join join_test j2
on(j1.department=j2.department and j1.name<>j2.name)
NAME DEPARTMENT andros sa steliso sa mary ba stav ba antonia la lambros ka
3 ответа
Правое и левое соединения выполняют одну и ту же функцию. Что отличается в ваших примерах - это таблицы, из которых вы ВЫБИРАЕТЕ.
Эти два запроса:
select j2.name,j2.department
from join_test j1 left join join_test j2
on(j1.department=j2.department and j1.name<>j2.name)
а также
select j1.name,j1.department
from join_test j1 right join join_test j2
on(j1.department=j2.department and j1.name<>j2.name)
Произведите тот же результат:
NAME DEPARTMENT
stelios sa
andros sa
stav ba
mary ba
(null) (null)
(null) (null)
Причина различий в результатах, которые вы видите между вашими левым и правым запросами, заключается в том, что в левом примере вы выбираете из таблицы "вождения" (левая таблица, J1). Объединение показывает все строки из управляющей таблицы (J1) и совпадающие строки (которые не отображаются) из правой или неприводной таблицы (J2).
В вашем правильном примере вы меняете соединение, но все еще выбираете из J1. Поскольку J1 теперь является неприводной таблицей, вы видите только совпадающие результаты J1. Если вы добавите столбцы J2 в выборку, вы увидите все ее строки:
NAME DEPARTMENT NAME DEPT
stelios sa andros sa
andros sa stelios sa
stav ba mary ba
mary ba stav ba
(null) (null) antonia la
(null) (null) lambros ka
Вы увидите тот же результат с левым соединением, но нулевые значения не были бы другой стороной.
В обоих случаях (нулевые) строки представляют строки из таблицы управления, которые не соответствуют таблице управления.
Это дает правильные результаты в SQL Fiddle (sqlfiddle.com/#!4/1e7075/2). Однако у меня есть подозрение. Возвращенные результаты:
NAME DEPARTMENT
stelios sa
andros sa
stav ba
mary ba
(null) (null)
(null) (null)
Я подозреваю, что как бы вы ни возвращали результаты (или смотрели на них), строки со всеми NULL
значения игнорируются. Попробуйте выбрать столбцы из j2
стол и посмотреть, если вы получите больше результатов.
здесь вы делаете самосоединение и комбинируете его с правильным внешним соединением с неравными условиями соединения;
Из того, что я понял: когда он запрашивает правильное соединение, это означает, что он будет извлекать записи только с правой стороны таблицы, где есть строки, соответствующие условиям соединения, и объединять их со строками с левой стороны (основная таблица) где условия соблюдены.
А также потому, что основная таблица - это таблица с левой стороны от, поэтому, когда вы выполняете левое соединение, она извлекает все записи из левой таблицы (основной таблицы) + записи из правой таблицы, где есть строки соответствуют условиям соединения.
Когда дело доходит до внутреннего соединения, оно будет извлекать только совпадающие записи (строки), в которых выполняются условия соединения из обеих таблиц. Даже основная таблица является левой таблицей, все равно строки из левой таблицы, где не выполняются условия, не будут включены в наборы результатов.
Мне потребовалось некоторое время, чтобы понять это, и я надеюсь, что это хорошо объясняет и может быть полезно (COZ, я также изо всех сил пытался понять это раньше).