Внешнее соединение более 1 таблицы
Допустим, у меня есть 5 таблиц следующим образом:
CREATE TABLE T1 (
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
CITY NUMERIC,
SALARY NUMERIC);
CREATE TABLE T2 (
CITY NUMERIC,
DISTRICT NUMERIC);
CREATE TABLE T3 (
DISTRICT NUMERIC,
DOMAIN NUMERIC);
CREATE TABLE T4 (
DOMAIN NUMERIC,
DETAILS_BOOK NUMERIC);
CREATE TABLE T5 (
DETAILS_BOOK NUMERIC,
FIRST_NAME VARCHAR2(100),
LAST_NAME VARCHAR2(100),
EMAIL VARCHAR2(100));
INSERT INTO T1 VALUES ('john', 'doe',1001,1000);
INSERT INTO T1 VALUES ('jack', 'jill',1001,2000);
INSERT INTO T1 VALUES ('jeff', 'bush',1001,1500);
INSERT INTO T2 VALUES (1001,1);
INSERT INTO T3 VALUES (1,543);
INSERT INTO T4 VALUES (543,22);
INSERT INTO T5 VALUES (22,'john', 'doe','john@22.com');
INSERT INTO T5 VALUES (44,'john', 'doe','john@44.com');
INSERT INTO T5 VALUES (22,'jeff', 'bush','jeff@22.com');
INSERT INTO T5 VALUES (44,'jeff', 'bush','jeff@44.com');
Теперь я хочу, чтобы все записи из t1, с их зарплатами и электронными письмами, соответствовали таблицам t2, t3 и t4, так, чтобы результат был:
FIRST_NAME | LAST_NAME | SALARY | EMAIL
--------------------------------------------------
john | doe | 1000 | john@22.com
jeff | bush | 1500 | jeff@22.com
jack | jill | 2000 | (NULL)
то, что я получил так далеко, это:
SELECT T1.FIRST_NAME, T1.LAST_NAME,T1.SALARY,T5.EMAIL
FROM T1,T2,T3,T4,T5
WHERE T1.FIRST_NAME = T5.FIRST_NAME (+)
and T1.LAST_NAME = T5.LAST_NAME(+)
AND T1.CITY = T2.CITY
AND T2.DISTRICT = T3.DISTRICT
AND T3.DOMAIN = T4.DOMAIN
AND T4.DETAILS_BOOK = T5.DETAILS_BOOK
который возвращает только первые две строки.
1 ответ
Попробуйте это вместо этого:
SELECT
T1.FIRST_NAME,
T1.LAST_NAME,
T1.SALARY,
T5.EMAIL
FROM T1
LEFT JOIN T2 ON T1.CITY = T2.CITY
LEFT JOIN T3 ON T2.DISTRICT = T3.DISTRICT
LEFT JOIN T4 ON T3.DOMAIN = T4.DOMAIN
LEFT JOIN T5 ON T4.DETAILS_BOOK = T5.DETAILS_BOOK
AND T1.FIRST_NAME = T5.FIRST_NAME
AND T1.LAST_NAME = T5.LAST_NAME;
SQL Fiddle Demo
Это даст вам:
| FIRST_NAME | LAST_NAME | SALARY | EMAIL |
-------------------------------------------------
| john | doe | 1000 | john@22.com |
| jeff | bush | 1500 | jeff@22.com |
| jack | jill | 2000 | (null) |
Проблема в том, что INNER JOIN
после OUTER JOIN
делает ваши объединения работает как INNER
потому что, внутренние объединения устраняют те непревзойденные ряды, которые идут от внешних объединений.
Обратите внимание: я использовал явный ANSI SQL-92 LEFT OUTER JOIN
синтаксис, вместо старого неявного OUTER
а также INNER
присоединиться к синтаксису, который вы использовали в своем запросе.
Пожалуйста, попробуйте использовать LEFT OUTER JOIN
вместо старого синтаксиса внешнего соединения, и избежать INNER JOIN
после OUTER JOIN
s.
Для более подробной информации, смотрите эти:
Обновить:
Когда у вас есть много ссылок на таблицы в FROM
оговорка с JOIN
между ними каждая таблица соединяется со следующей таблицей, начиная с FROM
пункт1, приводит к временному набору результатов, затем этот временный набор результатов объединяется со следующей таблицей и так далее. В случае OUTER JOIN
есть левое или правое:
LEFT JOIN
будет включать эти несопоставленные строки из левой таблицы, где, как,RIGHT JOIN
будет включать эти несопоставленные строки из правой таблицы.
В зависимости от данных, которые вы хотите выбрать, вы должны следить за этими таблицами с двух сторон JOIN
оператор и порядок их.
1:Это просто логический порядок обработки запросов, но в фактическом порядке всегда до оптимизатора запросов.