Своеобразный случай синтаксиса внешнего соединения Oracle

16

Я видел следующее в запросе, который должен был быть перенесен из синтаксиса внешнего соединения Oracle в стандартный синтаксис внешнего соединения SQL:

SELECT ...
FROM A, B, C, D, E
WHERE A.A_ID = B.A_ID
AND B.B_ID = C.A_ID(+)
AND B.B_KEY = C.B_KEY(+)
AND C.C_ID = D.C_ID(+)
AND B.A_ID = E.A_ID(+)
AND B.B_KEY = E.B_KEY(+)
AND 'CONSTANT' = C.X_ID(+)

Теперь перевод синтаксиса внешнего соединения обычно довольно механический процесс, но эта последняя строка меня озадачила. Что это означает? Какой эффект это имеет?

Питер Айзентраут
источник

Ответы:

11

Я пытался выполнить механический процесс. Я надеюсь, что я помню это правильно.

Это ведет к:

SELECT ...
FROM A
         join B on A.A_ID = B.A_ID
    left join C on B.B_ID = C.A_ID and B.B_KEY = C.B_KEY and 'CONSTANT' = C.X_ID
    left join D on C.C_ID = D.C_ID
    left join E on B.A_ID = E.A_ID and B.B_KEY = E.B_KEY

Короче говоря, я думаю, что ответ Ли Риффеля правильный.

Заметка

в старые времена правило для запоминания было: оракул, где Aa = Bb (+) становится Aa * = Bb в старом синтаксисе SQL-Server, плюс идет в противоположную сторону и становится звездой, что означает соединение слева B на Aa = Bb

bernd_k
источник
10

Строка требует, чтобы c.X_ID был равен постоянному значению или чтобы не было записи из таблицы C. Конечно, поскольку он остается присоединенным, он не ограничивает записи из таблицы A, а ограничивает только записи из таблицы C, которые объединяются. Вот демонстрация:

Настроить:

CREATE TABLE T1 as (select rownum+1 t1_id from dual connect by rownum <= 4);
CREATE TABLE T2 as (
   select rownum t1_id, DECODE(rownum,2,'CONSTANT',3,'NoMatch') CompareField 
   from dual connect by rownum <= 3
);
SELECT * FROM T1;
SELECT * FROM T2;

Результаты:

SELECT T1.t1_id, T2.t1_id, T2.CompareField
FROM T1, T2
WHERE T1.t1_id = T2.t1_id(+)
AND 'CONSTANT' = T2.CompareField(+)
ORDER BY 1;

Или:

SELECT T1.t1_id, T2.t1_id, T2.CompareField
FROM T1 LEFT JOIN T2 ON T1.t1_id = T2.t1_id 
AND 'CONSTANT' = T2.CompareField
ORDER BY 1;
Ли Риффель
источник