Pchełki SQL: LEFT JOIN

https://xpil.eu/dJ7

Dzisiaj coś absolutnie podstawowego, o czym jednak zdarza się zapomnieć nawet starym wyjadaczom (zwłaszcza po trzech zarwanych nockach tuż przed wypuszczeniem gotowego produktu na rynek, albo w środowisko produkcyjne).

Operator LEFT JOIN działa w ten sposób, że zwraca wszystkie rekordy z tabeli głównej...

Dla jasności, mamy takie zapytanie:

SELECT A.*, B.*
FROM A
LEFT JOIN B
  ON A.SOME_ID = B.SOME_ID
  AND A.SOME_OTHER_ID = B.SOME_OTHER_ID

"Tabelą główną" jest tu A, a "tabelą dołączaną" - B.

... wszystkie, powiadam, rekordy z tabeli głównej oraz te rekordy z tabeli dołączanej, które pasują (czyli mają takie same wartości w kolumnach SOME_ID i SOME_OTHER_ID). Jeżeli rekordów pasujących do danego SOME_ID i SOME_OTHER_ID jest po stronie tabeli B więcej niż jeden, na wyjściu dostaniemy duplikaty w kolumnach tabeli A. Jeżeli rekordów pasujących nie ma, na wyjściu dostaniemy NULL we wszystkich kolumnach tabeli B. Istotne jest tu, że LEFT JOIN - w odróżnieniu od "zwykłego" JOIN - nigdy nie wyeliminuje rekordów z tabeli głównej (A). Może je co najwyżej zwielokrotnić.

Na ogół wszyscy o tym pamiętają, ale czasem zdarza się pomyłka, o taka:

SELECT A.*, B.*
FROM A
LEFT JOIN B
  ON A.SOME_ID = B.SOME_ID
WHERE A.SOME_OTHER_ID = B.SOME_OTHER_ID

Logika niby ta sama, bo w obydwu przypadkach poszukujemy rekordów z obydwu tabel, które mają takie same wartości w kolumnach SOME_ID i SOME_OTHER_ID, ale jednak nie do końca.

Przesunięcie drugiego warunku z bloku JOIN do bloku WHERE powoduje, że warunek ten zadziała na wynikach JOIN-a, a więc odfiltruje rekordy, które mają inne wartości w kolumnach SOME_OTHER_ID. W efekcie drugie zapytanie zwróci mniej rekordów od pierwszego (rzecz jasna przy założeniu, że niedopasowane rekordy istnieją).

Uwaga na koniec: technicznie rzecz biorąc, drugie z powyższych zapytań NIE jest błędem. Jest po prostu innym zapytaniem. Czasami zachodzi potrzeba założenia filtra na wynikach generowanych przez LEFT JOIN. Trzeba tylko pamiętać o logicznej różnicy między umieszczeniem warunku w samym JOIN-ie, a umieszczeniem go w klauzuli WHERE całego zapytania.

https://xpil.eu/dJ7

Leave a Comment

Komentarze mile widziane.

Jeżeli chcesz do komentarza wstawić kod, użyj składni:
[code]
tutaj wstaw swój kod
[/code]

Jeżeli zrobisz literówkę lub zmienisz zdanie, możesz edytować komentarz po jego zatwierdzeniu.