Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle- Left Outer Join für mehrere Tabellen, die nicht die gewünschten Nullwerte zurückgeben

Sie müssen besser verstehen, wie ein LEFT JOIN funktioniert (Outer Joins im Allgemeinen - Left/Right und Full [Outer] Join)

Der LEFT JOIN wird immer in zwei Schritten durchgeführt:

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

Schritt 1 - Der LEFT JOIN wird zuerst ausgeführt (unter Verwendung der in der ON-Klausel angegebenen Bedingungen, um zwei Tabellen zu verbinden)
Schritt 2 - Die WHERE-Bedingungen werden auf eine Ergebnismenge angewendet, die durch den Join in Schritt 1 generiert wurde

Wie der LEFT JOIN funktioniert - eine kurze Erinnerung:LEFT JOIN gibt immer ALLE Zeilen aus der linken Tabelle zurück, sogar die Zeilen, für die es keine Übereinstimmung in der rechten Tabelle gibt. Wenn es keine Übereinstimmung gibt (die ON-Bedingung wird als falsch ausgewertet), gibt LEFT JOIN NULLen für die rechte Tabelle zurück.
Der RIGHT JOIN funktioniert auf die gleiche Weise, aber er gibt alle Zeilen aus der RIGHT-Tabelle zurück, nicht aus der linken als LEFT JOIN.

SO, wenn Sie diese Abfrage haben:

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'

die Datenbank führt zuerst den LEFT JOIN durch, das heißt:

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

Die obige Abfrage ergibt das folgende Ergebnis (beachten Sie NULLen in den letzten 3 Zeilen auf der rechten Seite):

|   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) |

Und dann führt die Datenbank die WHERE-Bedingung für die obige Ergebnismenge aus:

WHERE H.STATUS='COMPLETED'

Seit NULL='COMPLETED' zu FALSE ausgewertet wird, lautet das Endergebnis der Abfrage:

|     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 |

das heißt:alle NULLen wurden übersprungen.
Sehen Sie sich diese Demo an:http://sqlfiddle .com/#!9/e2ed0/3

Wenn Sie auch Datensätze mit NULL-Werten erhalten möchten, müssen Sie diese Bedingung ändern in:

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

Sie können diese Bedingung auch aus der WHERE-Klausel entfernen und zur ON-Bedingung des LEFT JOIN hinzufügen, das heißt:

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' )

siehe die letzte Abfrage in dieser Demo:http://sqlfiddle.com/#!9/e2ed0 /3