sql >> Database >  >> RDS >> Oracle

Oracle- Left outer join op meerdere tabellen die de gewenste null-waarden niet retourneert

U moet beter begrijpen hoe een LEFT JOIN werkt (outer joins in het algemeen - left/right en full [outer] join)

De LEFT JOIN wordt altijd in twee stappen uitgevoerd:

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

Stap 1 - de LEFT JOIN wordt eerst uitgevoerd (gebruik de voorwaarden die zijn gespecificeerd in de ON-clausule om twee tabellen samen te voegen)
Stap 2 - de WHERE-voorwaarden worden toegepast op een resultaat dat is gegenereerd door de join in stap 1

Hoe de LEFT JOIN werkt - een snelle herinnering:LEFT JOIN retourneert altijd ALLE rijen uit de linkertabel, zelfs deze rijen waarvoor er geen overeenkomst is in de rechtertabel. Als er geen overeenkomst is (de ON-voorwaarde is onwaar), retourneert LEFT JOIN NULL-waarden voor de rechtertabel.
De RIGHT JOIN werkt op dezelfde manier, maar retourneert alle rijen uit de RIGHT-tabel, niet de linker als LEFT JOIN.

Dus als je deze vraag hebt:

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'

de database voert eerst de LEFT JOIN uit, dat wil zeggen:

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

De bovenstaande query geeft het volgende resultaat (let op NULL's in de laatste 3 rijen aan de rechterkant):

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

En dan voert de database de WHERE-voorwaarde uit op de bovenstaande resultatenset:

WHERE H.STATUS='COMPLETED'

Sinds NULL='COMPLETED' evalueert naar FALSE, dan is het uiteindelijke resultaat van de zoekopdracht:

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

dat wil zeggen:alle NULL's zijn overgeslagen.
Bekijk deze demo:http://sqlfiddle .com/#!9/e2ed0/3

Als u ook records met NULL-waarden wilt krijgen, moet u deze voorwaarde wijzigen in:

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

u kunt deze voorwaarde ook verwijderen uit de WHERE-component en deze toevoegen aan de ON-voorwaarde van de LEFT JOIN, dat wil zeggen:

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

zie de laatste vraag in deze demo:http://sqlfiddle.com/#!9/e2ed0 /3




  1. gemarkeerde gebruiker met label op tijd voor elke maand

  2. ORA-01008:niet alle variabelen zijn gebonden. Ze zijn gebonden

  3. MySQL-kolom =0 retourneert waar

  4. Hoe schrijf ik een Oracle Insert-script met één veld als CLOB?