Caso de sintaxis de unión externa peculiar de Oracle

16

He visto lo siguiente en una consulta que se suponía que debía portarse desde la sintaxis de combinación externa de Oracle a la sintaxis de combinación externa estándar de 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(+)

Ahora traducir la sintaxis de unión externa es normalmente un proceso bastante mecánico, pero esa última línea me desconcertó. Qué significa eso? ¿Qué efecto tiene?

Peter Eisentraut
fuente

Respuestas:

11

Traté de realizar el proceso mecánico. Espero recordarlo bien.

Esto lleva a:

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

En resumen, creo que la respuesta de Leigh Riffel es correcta.

Nota

en los viejos tiempos, la regla para memorizar era: oráculo donde Aa = Bb (+) se convierte en Aa * = Bb en la sintaxis antigua de SQL Server, el signo más va al lado opuesto y se convierte en una estrella, lo que significa que A se une a B en Aa = Bb

bernd_k
fuente
10

La línea requiere que c.X_ID sea igual al valor constante o que no haya ningún registro de la tabla C. Por supuesto, dado que se deja unido, no limitará los registros de la tabla A, solo limitará los registros de la tabla C que se unen. Aquí hay una demostración:

Preparar:

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;

Resultados:

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;

O:

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;
Leigh Riffel
fuente