W SQL JOIN służy do łączenia tabel. W SQL operacja JOIN jest jedną z najczęściej wykonywanych operacji pozwalającą korzystać z danych podzielonych między różne tabele.

W tym kursie poznasz:

  • Składnię JOIN w SQL
  • Przykłady JOIN
  • Przykłady JOIN wielu tabel

Ten kurs jest częścią cyklu Kurs SQL

Zapisz się na autorskie Szkolenie SQL

Przygotowanie bazy danych

Aby pokazać działanie operacji JOIN w pierwszej kolejności musimy przygotować odpowiednio bazę danych. Aby lepiej zrozumieć ten wpis polecam zapoznać się z kursami:

Do testów przygotujemy bazę danych z kursu SQL INSERT | DELTE | UPDATE. Jeżeli jeje nie masz wystarczy, ze wykonasz poniższy skrypt:

CREATE TABLE CENNIK (
    ROZMIAR VARCHAR2(3 CHAR)
  , CENA    NUMBER
  
  , CONSTRAINT CENNIK_PK PRIMARY KEY (ROZMIAR) 
);

CREATE TABLE MENU (
    ID      NUMBER GENERATED ALWAYS AS IDENTITY
  , NAZWA   VARCHAR2(20 CHAR)
  , ROZMIAR VARCHAR2(3 CHAR)
  
  , CONSTRAINT MENU_PK PRIMARY KEY (ID)
  , CONSTRAINT MENU_CENNIK_FK FOREIGN KEY (ROZMIAR) REFERENCES CENNIK(ROZMIAR)
);

CREATE TABLE KLIENT (
    ID       NUMBER GENERATED ALWAYS AS IDENTITY
  , IMIE     VARCHAR2(20 CHAR)
  , NAZWISKO VARCHAR2(20 CHAR)
  
  , CONSTRAINT KLIENT_PK PRIMARY KEY (ID)
);

CREATE TABLE ADRES (
    ID_ADRESU     NUMBER GENERATED ALWAYS AS IDENTITY
  , ULICA         VARCHAR2(20 CHAR)
  , NR_BLOKU      VARCHAR2(10 CHAR)
  , NR_MIESZKANIA VARCHAR2(10 CHAR)
  , MIASTO        VARCHAR2(20 CHAR)
  
  , CONSTRAINT ADRES_PK PRIMARY KEY (ID_ADRESU)
);

CREATE TABLE ZAMOWIENIA (
    ID_PIZZA        NUMBER
  , ID_KLIENTA      NUMBER
  , ID_ADRESU       NUMBER
  , DATA_ZAMOWIENIA DATE
  
  , CONSTRAINT ZAM_PIZZA_FK FOREIGN KEY (ID_PIZZA) REFERENCES MENU(ID)
  , CONSTRAINT ZAM_KLIENT_FK FOREIGN KEY (ID_KLIENTA) REFERENCES KLIENT(ID)
  , CONSTRAINT ZAM_ADRES_FK FOREIGN KEY (ID_ADRESU) REFERENCES ADRES(ID_ADRESU)
);

a do wypełnienia powyższej struktury danymi możesz wykonać poniższe inserty:

INSERT INTO CENNIK (ROZMIAR, CENA) VALUES ('L', 15);
INSERT INTO CENNIK (ROZMIAR, CENA) VALUES ('XL', 20);
INSERT INTO CENNIK (ROZMIAR, CENA) VALUES ('XXL', 25);

INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Margherita', 'XXL');
INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Margherita', 'L');
INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Pepperonia', 'L');
INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Hawajska', 'L');
INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Margherita', 'XL');
INSERT INTO MENU (NAZWA, ROZMIAR) VALUES ('Wiejska', 'XXL');

INSERT INTO KLIENT (IMIE, NAZWISKO) VALUES ('Jan', 'Kowalski');
INSERT INTO KLIENT (IMIE, NAZWISKO) VALUES ('Piotr', 'Nowak');
INSERT INTO KLIENT (IMIE, NAZWISKO) VALUES ('Anna', 'Zaradna');
INSERT INTO KLIENT (IMIE, NAZWISKO) VALUES ('Kamila', 'Zaradna');

INSERT INTO ADRES (ULICA, NR_BLOKU, NR_MIESZKANIA, MIASTO) VALUES ('Hery', 5, null, 'Warszawa');
INSERT INTO ADRES (ULICA, NR_BLOKU, MIASTO) VALUES ('Domaniewska', 2, 'Poznań');
INSERT INTO ADRES (ULICA, MIASTO) VALUES ('JP2', 'Warszawa');
INSERT INTO ADRES (ULICA, MIASTO) VALUES ('JP2', 'Wrocław');

INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, ID_ADRESU, DATA_ZAMOWIENIA) VALUES (1, 1, 1, '2019-01-01');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, ID_ADRESU, DATA_ZAMOWIENIA) VALUES (2, 2, 2, '2019-01-02');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, ID_ADRESU, DATA_ZAMOWIENIA) VALUES (3, 2, 2, '2019-01-02');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, DATA_ZAMOWIENIA) VALUES (4, 3, '2019-01-03');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, DATA_ZAMOWIENIA) VALUES (5, 3, '2019-01-03');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, DATA_ZAMOWIENIA) VALUES (6, 3, '2019-01-03');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, ID_ADRESU, DATA_ZAMOWIENIA) VALUES (2, 3, 3, '2019-01-05');
INSERT INTO ZAMOWIENIA (ID_PIZZA, ID_KLIENTA, ID_ADRESU, DATA_ZAMOWIENIA) VALUES (3, 4, 4, '2019-01-06');
COMMIT;

Po wykonaniu powyższych skryptów masz już bazę na której możemy uczyć się operacji JOIN.

Składnia w SQL JOIN

Operacja JOIN służy do łączenia dwóch tabel. Aby móc je połączyć ze sobą potrzebna jest para najczęściej kluczy po których możemy je ze sobą połączyć. Dla przykładu tabela CENNIK ma klucz o nazwie ROZMIAR po którym możemy wyszukać ceny w tabeli CENNIK.

Zobaczmy więc jak wygląda składnia operacji JOIN w SQL.

SELECT
    *
FROM TABELA_1
JOIN TABELA_2 ON TABELA_2.KOLUMNA_X = TABELA_1.KOLUMNA_Y
WHERE ...

Tak więc aby połączyć tabelę należy podać słowo kluczowe JOIN. Następnie nazwę tabeli którą chcemy złączyć. Kolejno słowo kluczowe ON i dalej warunek lub warunki złączenia. Najczęściej warunkami złączenia są kolumny które są FK i PK (o tym czym są pisałem w tym kursie).

Należy wspomnieć, że powyższa składnia nie jest jedyną choć chyba najczęściej występującą. W innej składni nie musi występować słowo kluczowe ON a warunek złączenia występuje w sekcje WHERE jak poniżej:

SELECT
    *
FROM TABELA_1
JOIN TABELA_2
WHERE TABELA_2.KOLUMNA_X = TABELA_1.KOLUMNA_Y

Wynik obu zapytań będzie taki sam.

Łączenie wielu tabel przy pomocy sql join

Częstym problemem dla osób początkujących z SQL jest problem łączenia wielu tabel. W sytuacji łączenia dwóch tabel operacja join wydaje się intuicyjna. Gdy łączymy więcej niż dwie tabele musimy szczególną uwagę zwrócić na to którą tabelę łączymy do której oraz jakie efekty przyniesie takie działanie. Dla porządku zobaczmy przykładową składnię łączenia wielu tabel. Może ona wyglądać jak poniżej:

SELECT
    *
FROM TABELA_1
JOIN TABELA_2 ON TABELA_2.KOLUMNA_X = TABELA_1.KOLUMNA_Y
JOIN TABELA_3 ON TABELA_3.KOLUMNA_Z = TABELA_2.KOLUMNA_XX
JOIN TABELA_4 ON TABELA_4.KOLUMNA_W = TABELA_1.KOLUMNA_K
WHERE ...

oraz przy równoważnego zapytania używając WHERE do Joinowania:

SELECT
    *
FROM TABELA_1
JOIN TABELA_2
JOIN TABELA_3
JOIN TABELA_4
WHERE TABELA_2.KOLUMNA_X = TABELA_1.KOLUMNA_Y
  AND TABELA_3.KOLUMNA_Z = TABELA_2.KOLUMNA_XX
  AND TABELA_4.KOLUMNA_W = TABELA_1.KOLUMNA_K

Gdy porównamy składnię zapytania dla dwóch i kilku tabel wydaje się ona logiczna. Każdą kolejną tabelę dodajemy do operacji JOIN oraz dodajemy warunek złączenia.

Operacja w SQL JOIN jest jedną z najważniejszych i może sprawić wiele niespodzianek początkującym dlatego poniżej znajduje się rozdział z przykładowymi zapytaniami, wynikami oraz ich analizą.

Przykłady w SQL JOIN

Skoro mamy już przygotowaną bazę danych oraz poznaliśmy składnię operacji JOIN przejdźmy do omówienia kilku przykładów aby lepiej zrozumieć działanie tej operacji.

Dla przypomnienia nasza baza danych wraz z danymi wygląda jak na poniższym zrzucie:

sql drop, alter, create table

Spróbujmy więc dla powyższej bazy danych sprawdzić ceny konkretnych pizz. W tym celu musimy połączyć dwie tabele: CENNIK i MENU. Obie tabele mają wspólną kolumnę po której można je połączyć tj. ROZMIAR. W związku z tym zapytanie może wyglądać jak poniżej:

SELECT 
    *
FROM CENNIK
JOIN MENU ON MENU.ROZMIAR = CENNIK.ROZMIAR;

oraz wynik zapytania:

sql join

Powyższe zapytanie dzięki użyciu klauzuli SQL JOIN połączyło obie tabele dzięki czemu uzyskaliśmy wynik z 6 rekordami i 5 kolumnami. Gdy spojrzymy na diagram zobaczymy, że obie tabele zawierają kolumnę ROZMIAR. W wyniku jak widzimy kolumny ROZMIAR i ROZMIAR_1, pierwsza z nich dotyczy tabeli CENNIK a druga tabeli MENU. W sytuacji gdy JOINujemy tabele które mają kolumny o tej samej nazwie baza oracle dodaje do nazwy kolumny _1, _2, _3…

Można jednak zadać pytanie jak baza dokładnie dobrała rekordy do siebie? W klauzuli JOIN występuje sekcja z ON gdzie podajemy warunek złączenia. Oznacza to, że baza wybrała pierwszy rekord z tabeli CENNIK wzięła kolumnę ROZMIAR z wartością L i zaczęła wyszukiwać tych wartości w tabeli MENU. Znalazła takich rekordów 3 dlatego też połączyła je ze sobą. Następnie wzięła kolejny rekord z wartością XL i wykonała tą samą operację.

Można zadać w takim razie pytanie co się stanie gdy baza danych nie znajdzie odpowiedniego rekordu w drugiej tabeli? Rozważmy za tem inny przykład. Sprawdźmy na jakie adresy zamówione były konkretne zamówienia.

Aby wykonać takie zapytanie należy połączyć dwie tabele tj. ADRES i ZAMOWIENIA po kolumnach ID_ADRESU. Przykładowe zapytanie może wyglądać jak poniżej:

SELECT
    *
FROM ADRES
JOIN ZAMOWIENIA ON ZAMOWIENIA.ID_ADRESU = ADRES.ID_ADRESU;

Oraz wynik powyższego zapytania:

join sql

Jak widzimy w wyniku zapytania pojawiło się 5 rekordów z 8 występujących w tabeli ZAMOWIENIA. Stało się tak ponieważ tabela zamowienia w trzech rekordach w kolumnie id_adresu ma wartość null przez co nie może połączyć jej z żadną wartością z tabeli ADRES. W tej sytuacji baza danych pomija takie rekordy. Istnieje oczywiście możliwość dołączenia tych trzech rekordów jednak wymagana jest do tego operacja LEFT JOIN która będzie opisana w kolejnym kursie.

Można zatem zastanowić się co by się stało gdybyśmy w obu kolumnach JOINowanych mieli wartość NULL? Rozważmy poniższy przykład z bazą gdzie w dla przykładowego bloku mamy ponumerowane mieszkania oraz składzik który numeru nie ma. Dodatkowo mamy domofon przypisany do mieszkania oraz przycisk TEST bez podanego numeru i jedno wolne pole do uzupełnienia w przyszłości.

Wykonanie operacji JOIN na takich tabelach po kolumnach NR zwróci dwa rekordy ponieważ null nie jest równe null. Należy pamiętać, że przyrównanie null do jakiejkolwiek wartości da false nawet null do null.

Napiszmy teraz zapytanie nieco bardziej skomplikowane tj. zobaczmy jakie pizze zamawiali którzy klienci. Do tego celu potrzebujemy 3 tabel tj. MENU, ZAMOWIENIA i KLIENT. Przykładowe zapytanie może wyglądać jak poniżej:

SELECT
    *
FROM KLIENT
JOIN ZAMOWIENIA ON ZAMOWIENIA.ID_KLIENTA = KLIENT.ID
JOIN MENU ON MENU.ID = ZAMOWIENIA.ID_PIZZA;

Oraz wynik zapytania:

sql join 3 tables

Jak widzimy z powyższego wyniku łącznie mam 8 wyników tj. 8 zamówień przez różnych klientów a każde zamówienie dotyczyło jednej pizzy 🙂

Podsumowanie:

  • Składnia SQL JOIN składa się z dwóch członów tj. słowa kluczowego JOIN po którym podajemy nazwę tabeli oraz ON po którym podajemy warunek łączenia
  • Warunek złączenia można umieścić w części WHERE zapytania
  • Gdy łączymy rekordy które nie mają odpowiednika w tabeli łączonej taki rekord do wyniku nie trafi.
  • Łączenie kolumn w których znajdują się wartości null nie zwraca tych rekordów.
  • Istnieje możliwość łączenia wielu tabel w jednym zapytaniu
  • Jeżeli chcesz znaleźć więcej kursów dla średniozaawansowanych oraz poznać zasady optymalizacji zapytań zapoznaj się z pozostałymi kursami, sprawdź: Kurs Oracle SQL
  • Jeżeli chcesz poznać podstawy baz danych i kurs dla początkujących w SQL odwiedź Kurs SQL

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *