Oracle
 sql >> Baza danych >  >> RDS >> Oracle

Oracle — lewe sprzężenie zewnętrzne w wielu tabelach nie zwraca żądanych wartości null

Musisz lepiej zrozumieć, jak działa LEFT JOIN (ogólnie sprzężenia zewnętrzne - lewe/prawe i pełne [outer])

LEFT JOIN jest zawsze wykonywane w dwóch krokach:

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

Krok 1 - najpierw wykonywane jest LEFT JOIN (przy użyciu warunków określonych w klauzuli ON, aby połączyć dwie tabele)
Krok 2 - zastosowanie warunków WHERE do wyniku wygenerowanego przez złączenie w kroku 1

Jak działa LEFT JOIN - szybkie przypomnienie:LEFT JOIN zwraca zawsze WSZYSTKIE wiersze z lewej tabeli, nawet te, dla których nie ma dopasowania w prawej tabeli. Gdy nie ma dopasowania (warunek ON ma wartość false), LEFT JOIN zwraca NULL dla prawej tabeli.
RIGHT JOIN działa w ten sam sposób, ale zwraca wszystkie wiersze z tabeli RIGHT, a nie z lewej jako LEWY JOIN.

WIĘC, jeśli masz to zapytanie:

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'

baza danych najpierw wykonuje LEFT JOIN, czyli:

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

Powyższe zapytanie daje następujący wynik (zwróć uwagę na NULL w ostatnich 3 wierszach po prawej stronie):

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

Następnie baza danych wykonuje warunek WHERE na powyższym zestawie wyników:

WHERE H.STATUS='COMPLETED'

Ponieważ NULL='COMPLETED' zwraca FALSE, to ostateczny wynik zapytania to:

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

czyli:wszystkie wartości NULL zostały pominięte.
Zobacz to demo:http://sqlfiddle .com/#!9/e2ed0/3

Jeśli chcesz otrzymać również rekordy z wartościami NULL, musisz zmienić ten warunek na:

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

możesz również usunąć ten warunek z klauzuli WHERE i dodać go do warunku ON LEFT JOIN, czyli:

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

zobacz ostatnie zapytanie w tym demo:http://sqlfiddle.com/#!9/e2ed0 /3




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Błąd wyjścia SQL Fiddle

  2. Wstawianie ciągu znaków z podwójnymi cudzysłowami do tabeli

  3. Czy %NOTFOUND może zwrócić wartość null po pobraniu?

  4. Proszę o podanie kodu ceny tylko wtedy, gdy wpisz :=E

  5. Jak radzić sobie z sekundami przestępnymi w Oracle