sql >> Databasteknik >  >> RDS >> Oracle

Oracle- Vänster yttre koppling på flera tabeller returnerar inte önskade nollvärden

Du måste få en bättre förståelse för hur en LEFT JOIN fungerar (yttre kopplingar i allmänhet - vänster/höger och full [outer] koppling)

LEFT JOIN utförs alltid i två steg:

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

Steg 1 - LEFT JOIN utförs först (med villkor som specificeras i ON-satsen för att sammanfoga två tabeller)
Steg 2 - WHERE-villkoren tillämpas på ett resultat som genereras av sammanfogningen i steg 1

Hur LEFT JOIN fungerar - en snabb påminnelse:LEFT JOIN returnerar alltid ALLA rader från den vänstra tabellen, även dessa rader som det inte finns någon matchning för i den högra tabellen. När det inte finns någon matchning (PÅ-villkoret utvärderas till falskt), returnerar LEFT JOIN NULL för den högra tabellen.
RIGHT JOIN fungerar på samma sätt, men den returnerar alla rader från den HÖGER tabellen, inte den vänstra. som VÄNSTER JOIN.

SÅ om du har den här frågan:

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'

databasen utför först LEFT JOIN, det vill säga:

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

Ovanstående fråga ger följande resultat (notera NULL i de sista 3 raderna på höger sida):

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

Och sedan utför databasen WHERE-villkoret på ovanstående resultatuppsättning:

WHERE H.STATUS='COMPLETED'

Eftersom NULL='COMPLETED' utvärderas till FALSE, då är det slutliga resultatet av frågan:

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

det vill säga:alla NULLs hoppades över.
Se denna demo:http://sqlfiddle .com/#!9/e2ed0/3

Om du även vill få poster med NULL-värden måste du ändra detta villkor till:

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

du kan också ta bort detta villkor från WHERE-satsen och lägga till det till ON-villkoret för LEFT JOIN, det vill säga:

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

se den sista frågan i denna demo:http://sqlfiddle.com/#!9/e2ed0 /3




  1. Ordningsföljd för uttalandeutvärdering och variabeltilldelning i MySQL UNIONs

  2. Hur genererar man kodavsnittet som de som genereras av Google med PHP och MySQL?

  3. DOs och DONTs för index

  4. MySQL Välj rader med en tangent eller fall tillbaka för att välja som standardnyckel