sql >> Base de Datos >  >> RDS >> Oracle

Oracle:combinación externa izquierda en varias tablas que no devuelve los valores nulos deseados

Necesita comprender mejor cómo funciona LEFT JOIN (uniones externas en general:combinación izquierda/derecha y completa [externa])

LEFT JOIN siempre se realiza en dos pasos:

SELECT ....
FROM table1
LEFT JOIN table1 ON join_conditions
WHERE where_conditions

Paso 1:primero se realiza LEFT JOIN (usando las condiciones especificadas en la cláusula ON para unir dos tablas)
Paso 2:se aplican las condiciones WHERE a un resultado generado por la unión en el paso 1

Cómo funciona LEFT JOIN:un recordatorio rápido:LEFT JOIN devuelve siempre TODAS las filas de la tabla de la izquierda, incluso aquellas filas para las que no hay coincidencias en la tabla de la derecha. Cuando no hay ninguna coincidencia (la condición ON se evalúa como falsa), LEFT JOIN devuelve valores NULL para la tabla derecha.
RIGHT JOIN funciona de la misma manera, pero devuelve todas las filas de la tabla RIGHT, no de la izquierda como UNIÓN IZQUIERDA.

Entonces, si tiene esta consulta:

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H
ON S.TABLE_ID=H.TABLE_ID
WHERE H.STATUS='COMPLETED'

la base de datos primero realiza LEFT JOIN, es decir:

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H
ON S.TABLE_ID=H.TABLE_ID

La consulta anterior da el siguiente resultado (observe los valores NULL en las últimas 3 filas del lado derecho):

|   S.GROUP | S.TABLE_ID |                 H.RUN_DATE |  H.STATUS |
|-----------|------------|----------------------------|-----------|
|     Sales |       1210 |  January, 05 2016 00:00:00 | COMPLETED |
|     Sales |       1210 | February, 05 2016 00:00:00 | COMPLETED |
| Reference |       1211 | February, 05 2016 00:00:00 | COMPLETED |
| Reference |       1211 |    March, 05 2016 00:00:00 | COMPLETED |
| Marketing |       1230 |  January, 05 2016 00:00:00 | COMPLETED |
| Marketing |       1230 |    March, 05 2016 00:00:00 | COMPLETED |
|     Sales |       1245 |                     (null) |    (null) |
| Reference |       1650 |                     (null) |    (null) |
|     Sales |       1784 |                     (null) |    (null) |

Y luego la base de datos realiza la condición WHERE en el conjunto de resultados anterior:

WHERE H.STATUS='COMPLETED'

Desde NULL='COMPLETED' se evalúa como FALSO, entonces el resultado final de la consulta es:

|     GROUP | TABLE_ID |                   RUN_DATE |    STATUS |
|-----------|----------|----------------------------|-----------|
|     Sales |     1210 |  January, 05 2016 00:00:00 | COMPLETED |
|     Sales |     1210 | February, 05 2016 00:00:00 | COMPLETED |
| Reference |     1211 | February, 05 2016 00:00:00 | COMPLETED |
| Reference |     1211 |    March, 05 2016 00:00:00 | COMPLETED |
| Marketing |     1230 |  January, 05 2016 00:00:00 | COMPLETED |
| Marketing |     1230 |    March, 05 2016 00:00:00 | COMPLETED |

es decir:se omitieron todos los valores NULL.
Vea esta demostración:http://sqlfiddle .com/#!9/e2ed0/3

Si desea obtener también registros con valores NULOS, debe cambiar esta condición a:

WHERE ( H.STATUS='COMPLETED' OR H.STATUS IS NULL )

también puede eliminar esta condición de la cláusula WHERE y agregarla a la condición ON de LEFT JOIN, es decir:

SELECT S.GROUP,S.TABLE_ID,H.RUN_DATE,H.STATUS 
FROM source_table S 
LEFT JOIN HISTORY H
ON ( S.TABLE_ID=H.TABLE_ID AND H.STATUS='COMPLETED' )

vea la última consulta en esta demostración:http://sqlfiddle.com/#!9/e2ed0 /3