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