Pregunta Left Outer Join usando el signo + en Oracle 11g


¿Alguien me puede decir si las siguientes 2 consultas son un ejemplo de Unión externa izquierda o Unión externa derecha?

Table Part:
Name         Null?       Type
PART_ID      NOT NULL    VARCHAR2(4)
SUPPLIER_ID              VARCHAR2(4)

PART_ID SUPPLIER_ID
P1      S1
P2      S2
P3  
P4  

Table Supplier:
Name            Null?     Type
SUPPLIER_ID NOT NULL      VARCHAR2(4)
SUPPLIER_NAME   NOT NULL  VARCHAR2(20)

SUPPLIER_ID  SUPPLIER_NAME
S1           Supplier#1
S2           Supplier#2
S3           Supplier#3

Visualice todas las piezas, independientemente de si un proveedor las suministra o no:

SELECT P.Part_Id, S.Supplier_Name
DESDE la Parte P, Proveedor S
DONDE P.Supplier_Id = S.Supplier_Id (+)

SELECT P.Part_Id, S.Supplier_Name
DESDE la Parte P, Proveedor S
WHERE S.Supplier_Id (+) = P.Supplier_Id

¡Gracias!


73
2017-07-02 19:50


origen


Respuestas:


TableA LEFT OUTER JOIN TableB es equivalente a TableB RIGHT OUTER JOIN Table A.

En Oracle, (+) denota la tabla "opcional" en JOIN. Entonces, en su primera consulta, es un P LEFT OUTER JOIN S. En su segunda consulta, es S RIGHT OUTER JOIN P. Son funcionalmente equivalentes.

En la terminología, DERECHA o IZQUIERDA especificar qué lado de la unión siempre tiene un registro, y el otro lado puede ser nulo. Entonces en una P LEFT OUTER JOIN S, P siempre tendrá un registro porque está en el LEFT, pero S podría ser nulo.

Ver este ejemplo de java2s.com para una explicación adicional.


Para aclarar, supongo que estoy diciendo que la terminología no importa, ya que solo está ahí para ayudar a visualizar. Lo que importa es que entiendas el concepto de cómo funciona.


DERECHA vs IZQUIERDA

He visto cierta confusión sobre lo que importa para determinar el DERECHO frente a la IZQUIERDA en la sintaxis de unión implícita.

IZQUIERDA COMBINACIÓN EXTERNA

SELECT *
FROM A, B
WHERE A.column = B.column(+)

DERECHA UNIÓN EXTERIOR

SELECT *
FROM A, B
WHERE B.column(+) = A.column

Todo lo que hice fue intercambiar lados de los términos en la cláusula WHERE, pero todavía son funcionalmente equivalentes. (Consulte más arriba en mi respuesta para obtener más información al respecto.) La ubicación del (+) determina DERECHA o IZQUIERDA. (Específicamente, si el (+) está a la derecha, es un UNIÓN IZQUIERDA. Si (+) está a la izquierda, es un DERECHO A UNIRSE).


Tipos de JOIN

Los dos estilos de JOIN son uniones implícitas y uniones explícitas. Son diferentes estilos de escritura de JOIN, pero son funcionalmente equivalentes.

Ver esta pregunta SO.

Uniones Implícitas simplemente liste todas las tablas juntas. Las condiciones de unión se especifican en una cláusula WHERE.

Implique JOIN

SELECT *
FROM A, B
WHERE A.column = B.column(+)

Uniones explícitas asociar condiciones de unión con la inclusión de una tabla específica en lugar de una cláusula WHERE.

Explicit JOIN

SELECT *
FROM A
LEFT OUTER JOIN B ON A.column = B.column

Estas Los JOIN implícitos pueden ser más difíciles de leer y comprender, y también tienen algunas limitaciones ya que las condiciones de combinación se mezclan en otras condiciones DONDE. Como tal, los JOINs implícitos generalmente se recomiendan en contra a favor de la sintaxis explícita.


172
2017-07-02 20:02



Esas dos consultas están funcionando OUTER JOIN. Vea abajo

Oracle recomienda que utilice la sintaxis OUTER JOIN de la cláusula FROM   en lugar del operador de Oracle join. Consultas de unión externa que usan   El operador Oracle join (+) está sujeto a las siguientes reglas y   restricciones, que no se aplican a la cláusula FROM OUTER JOIN   sintaxis:

  • No puede especificar el operador (+) en un bloque de consulta que también   contiene la sintaxis de unión de la cláusula FROM.

  • El operador (+) solo puede aparecer en la cláusula WHERE o, en el   contexto de la correlación izquierda (cuando se especifica la cláusula TABLE) en el   Cláusula FROM, y solo se puede aplicar a una columna de una tabla o vista.

  • Si A y B están unidos por múltiples condiciones de unión, entonces debes usar   el operador (+) en todas estas condiciones. Si no lo haces, entonces   Oracle Database devolverá solo las filas resultantes de un simple   únete, pero sin una advertencia o error para aconsejarte que no   tener los resultados de una combinación externa.

  • El operador (+) no produce una combinación externa si especifica uno   tabla en la consulta externa y la otra tabla en una consulta interna.

  • No puede usar el operador (+) para unir una tabla externamente a sí mismo,   aunque las auto uniones son válidas. Por ejemplo, la siguiente declaración   no es válido:

    -- The following statement is not valid:
    SELECT employee_id, manager_id
       FROM employees
       WHERE employees.manager_id(+) = employees.employee_id;
    

    Sin embargo, la siguiente auto unión es válida:

    SELECT e1.employee_id, e1.manager_id, e2.employee_id
       FROM employees e1, employees e2
       WHERE e1.manager_id(+) = e2.employee_id
       ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
    
  • El operador (+) solo se puede aplicar a una columna, no a un arbitrario   expresión. Sin embargo, una expresión arbitraria puede contener uno o   más columnas marcadas con el operador (+).

  • Una condición WHERE que contiene el operador (+) no se puede combinar con   otra condición usando el operador lógico OR.

  • Una condición WHERE no puede usar la condición de comparación IN para comparar una   columna marcada con el operador (+) con una expresión.

Si la cláusula WHERE contiene una condición que compara una columna de   tabla B con una constante, luego el operador (+) debe aplicarse al   columna para que Oracle devuelva las filas de la tabla A para la cual   nulos generados para esta columna. De lo contrario, Oracle devuelve solo el   resultados de una unión simple.

En una consulta que realiza uniones externas de más de dos pares de tablas,   una sola tabla puede ser la tabla generada nula solo para otra   mesa. Por esta razón, no puede aplicar el operador (+) a las columnas   de B en la condición de unión para A y B y la condición de unión para B   y C. Consulte SELECCIONAR para la sintaxis de una unión externa.

Tomado de http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries006.htm


8
2017-07-02 20:01



Vi algunas contradicciones en las respuestas anteriores, intenté lo siguiente en Oracle 12c y la siguiente es correcta:

IZQUIERDA COMBINACIÓN EXTERNA

SELECT *
FROM A, B
WHERE A.column = B.column(+)

DERECHA UNIÓN EXTERIOR

SELECT *
FROM A, B
WHERE B.column(+) = A.column

1
2017-10-12 06:37



Hay información incorrecta en este hilo. Copié y pegué la información incorrecta:

IZQUIERDA COMBINACIÓN EXTERNA

SELECT *
FROM A, B
WHERE A.column = B.column(+)

DERECHA UNIÓN EXTERIOR

SELECT *
FROM A, B
WHERE B.column(+) = A.column

¡Lo de arriba es INCORRECTO! Es al revés. Cómo determiné que es incorrecto es del siguiente libro:

Oracle OCP Introducción a Oracle 9i: Guía de examen SQL. La Tabla 3-1 tiene un buen resumen sobre esto. No podía entender por qué mi SQL convertido no funcionaba correctamente hasta que fui a la vieja escuela y busqué en un libro impreso.

Aquí está el resumen de este libro, copiado línea por línea:

Oracle outer Join Syntax:

from tab_a a, tab_b b,                                       
where a.col_1 + = b.col_1                                     

Equivalente ANSI / ISO:

from tab_a a left outer join  
tab_b b on a.col_1 = b.col_1

Observe aquí que es el reverso de lo publicado anteriormente. Supongo que es posible que este libro tenga errata; sin embargo, confío más en este libro que en este hilo. Es una guía de examen para gritar en voz alta ...


-1
2017-09-25 15:59