Po serii wielu szkoleń dotyczących T-SQL w których słyszałem zdanie "nie rozumiem złączeń tabel" postanowiłem napisać krótkie wyjaśnienie 4 podstawowych typów złączeń dostępnych w SQL Server.

Posiadanie wiedzy w tym zakresie jest niezbędne i wynika z koncepcji działania relacyjnych baz danych. W sytuacji gdy dane biznesowe są umieszczone w dwóch i więcej tabelach zachodzi potrzeba połączenia wielu tabel w jeden wynik, jeden set.

Podstawowe typy złączeń z którymi musimy się zaprzyjaźnić to:

- INNER JOIN

- LEFT OUETR JOIN

- RIGHT OUTER JOIN

- FULL OUTER JOIN

W tym artykule celowo pominę wyjaśnienie i dyskusje na temat pisania Inner Join vs JOIN.

Oczywiście są inne typy złączeń, ale skupimy się tylko na tych najczęściej stosowanych i wynikających z aktualnego standardu SQL, zatem poniższe zapytania powinny działać również w innych systemach bazodanowych. Zacznijmy od przedstawienia modelu bazy danych utworzonego na nasze potrzeby wyłącznie z dwóch tabel: Klienci i Adresy. Tabela Klientów reprezentuje dane klienta natomiast tabela Adresów dane adresowe wspomnianych klientów.

Zacznijmy zatem od przedstawienia modelu.

Skrypt tworzący wszystkie obiekty wraz z przykładowymi danymi zostanie umieszczony na dole strony.

Zobaczmy zatem jak wyglądają przykładowe dane w tabeli.

Dla wyjaśnienia kolumna RodzajAdresu informuje jaki typ adresu jest w tym rekordzie (0- zameldowania, 1 - zamieszkania) stąd dwa rekordy dla jednego klienta).

INNER JOIN

Działanie tego typu złączeń najłatwiej opisać wykonując przykładowe połączenie powyższych tabel.

SELECT * FROM dbo.Klienci AS K
INNER JOIN dbo.Adresy AS A ON K.Id = A.IdKlienta

Wynik:

Zatem Inner Join łączy rekordy występujące w obu zbiorach po kluczu łączenia. Innymi słowy łączy wspólne elementy. Jeśli łączymy obie tabele po kolumnach K.Id oraz A.IdKlienta to nastąpiło połączenia klienta 1 z tabeli Klienci oraz obu rekordów posiadających w kolumnie IdKlienta wartość 1 z tabeli Adresy. Tak samo SQL Server połączył rekordy dla klienta 2. Rekord o identyfikatorze 3 z tabeli Klienci nie zostaje zwrócony, ponieważ nie istnieje w tabeli drugiej czyli Adresów (brak w kolumnie IdKlienta wartości 3 cokolwiek ona oznacza dla SQL Server).

LEFT OUTER JOIN

Napiszmy odpowiedni Select, który pokaże działanie tego typu złączeń.

SELECT * FROM dbo.Klienci AS K
LEFT OUTER JOIN dbo.Adresy AS A ON K.Id = A.IdKlienta

Wynik:

W tym rodzaju łączymy wszystkie rekordy z lewej tabeli z rekordami z tabeli prawej zgodnie z kluczem łączenia. Kluczowe w zrozumieniu tego typu łączenia są dwa pojęcia: wszystkie i lewej tabeli.

Przyjrzyjmy się zatem tym pojęciom. Zacznijmy od drugiego - lewa tabela. Lewa tabela oznacza tabele która występuje pierwsza w łączeniu (jest tabelą nadrzędną). W powyższym kodzie tabela która jest nadrzędna, występuja jako pierwsza - Klienci. Tabela Adresy jest podrzędną. Natomiast pojęcie wszystkie oznacza, że zostaną wszystkie rekordy zwrócone z tabeli lewej (Klienci) nawet jeśli nie istnieją odpowiednie rekordy w drugiej tabeli. Dlatego w wyniku otrzymujemy wszystkich klientów łącznie z klientem 3, które nie posiada adresu i dlatego w kolumnach pochodzących z tabeli Adresy widzimy same wartości NULL. Klienci, którzy posiadają adres zostali poprawnie połączeni.

RIGHT JOIN

Right Join działa analogicznie do Left Join z różnicą dzięki której otrzymujemy wszystkie rekordy z tabeli prawej (podrzędnej). Zatem w naszym przypadku otrzymamy wszystkie rekordy z tabeli Adresy niezależnie czy uda się połączyć rekordy czy nie.

SELECT * FROM dbo.Klienci AS K
RIGHT OUTER JOIN dbo.Adresy AS A ON K.Id = A.IdKlienta

Wynik:

Według powyższego wyjaśnienia otrzymaliśmy wszystkie rekordy z tabeli prawej, a więc adresów. Klient 3, który nie posiada adresu nie był w ógole brany pod uwagę, ze wględu na brak powiązania.

FULL JOIN

Full Join jest połączeniem RIGHT I LEFT JOIN oraz Inner JOIN. Łączy wszystkie rekordy z prawej i lewej strony nawet jeśli nie mają części wspólnych.

SELECT * FROM dbo.Klienci AS K
FULL OUTER JOIN dbo.Adresy AS A ON K.Id = A.IdKlienta

Wynik:

W przykładowym modelu bazy danych nie widać żadnej różnicy w stosunku do LEFT JOIN ze względu na tabelę Adresy, która nie posiada żadnego rekordu nie powiązanego z tabelą Klientów.


Umiejętne stosowanie odpowiednich Join'ów daje ogromne możliwości analizy danych. Użycie np warunku WHERE z NULL pozwala wykryć rekordy bez powiązania. Wyobraźmy sobie sytuacje gdzie model bazy danych przedstawia sklep internetowy i tabele: Zamówienia, Klienci. Zamówienie bez klientów nie powinno teoretycznie istnieć i można to w łatwy sposób sprawdzić.

SELECT * FROM dbo.Klienci AS K
LEFT OUTER JOIN dbo.Adresy AS A ON K.Id = A.IdKlienta
WHERE IdKlienta IS NULL

Efekt tego zapytania pozostanie pracą domową smiley

Powodzenia yes

Załączniki:
Pobierz plik (JOIN.sql)JOIN.sql[ ]1 kB