2013-06-14 3 views
7

Вот вопрос, который ошеломил меня в течение нескольких дней, и я искал и искал, но не смог найти убедительного ответа!2 Внешние соединения на одном столе?

Простой вопрос, почему он ограничен наличием 2 внешних соединений в SQL, на одной таблице, даже с разными используемыми столбцами, проверьте нижеприведенные запросы для лучшего понимания. Также я могу их преодолеть, используя вложенный подзапрос или ANSI-соединения, но тогда почему он даже ограничен в первую очередь с помощью оператора (+)!

В этом вопросе я имею в виду ошибки: «ORA-01417: таблица может быть внешней присоединился к более чем одним другому столу»

То, что я хочу спросить:

Почему это допускается:

select * from 
a, b, c 
where a.a1 = b.b1 
and a.a2 = c.c1 

И почему это не допускается:

select * from 
a, b, c 
where a.a1(+) = b.b1 
and a.a2(+) = c.c1 

Пожалуйста, оставьте ANSI и Вложенные подзапросы в одиночку

+6

Можете ли вы привести пример того, что вы пытаетесь сделать? Вы должны иметь возможность присоединяться ('inner' или' outer') к той же таблице столько раз, сколько необходимо ... – sgeddes

+2

Как сказал @sgeddes, вы, скорее всего, сбиты с толку. На Oracle – Lamak

+2

отсутствует ограничение «2 Внешних Соединения» Вы имеете в виду «ORA-01417: таблица может быть внешней, соединенной не более чем с одной другой таблицей»? –

ответ

10

Ограничение описано в документации Oracle: Outer Joins

Oracle рекомендует использовать ЕК OUTER JOIN синтаксиса, а не Oracle присоединиться к оператору. Внешнее объединение запросов, которые используют Оракул присоединиться к оператору (+) подлежат следующие правил и ограничений, которые не относятся к ЕКОМ OUTER JOIN синтаксис:

...

в запросе, что выполняет внешние объединения более двух пар таблиц, одна таблица может быть таблицей с генерированием нуля только для одной другой таблицы. По этой причине вы не можете применить оператор (+) к столбцам B в условии соединения для A и B и условие соединения для B и C. Обратитесь к SELECT для синтаксиса внешнего соединения.

, которые в основном означает (описанный в синтаксисе ANSI/ISO), что вы не можете иметь со старым (+) синтаксис, что вполне допустимо в ANSI/ISO:

--- Query 1 --- 
    a 
RIGHT JOIN b 
    ON a.x = b.x 
RIGHT JOIN c 
    ON a.y = c.y 

или:

--- Query 1b --- 
    c 
LEFT JOIN 
    b LEFT JOIN a 
     ON a.x = b.x 
    ON a.y = c.y 

Это только одно из многих ограничений старого синтаксиса Oracle.


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

--- Query 2 --- 
    a 
RIGHT JOIN c 
    ON a.y = c.y 
RIGHT JOIN b 
    ON a.x = b.x 

Смотрите тест в SQL-Fiddle. Так возникает вопрос. Как интерпретировать проприетарное соединение как запрос 1 или 2?

FROM a, b, c 
WHERE a.y (+) = c.y 
    AND a.x (+) = b.x 

Там нет ограничений, если на левой стороне (2 или более) внешние соединения появляется таблица. Это совершенно справедливо, даже со старым синтаксисом:

FROM a 
    LEFT JOIN b ON a.x = b.x 
  LEFT JOIN c ON a.y = c.y 
    ... 
    LEFT JOIN z ON a.q = z.q 

FROM a, b, ..., z 
WHERE a.x = b.x (+) 
  AND a.y = c.y (+) 
    ... 
    AND a.q = z.q (+) 
+0

Хорошее объяснение. –

+0

Это ограничение, кажется, было смягчено в 12c –

+0

@shonkylinuxuser Ссылка на это сообщение? Я бы подумал, что они удалят поддержку старого синтаксиса, а не улучшают его. –

Смежные вопросы