Przejdź do głównej zawartości

Moduł 5 – Praktyka: Złączenia tabel (JOIN)

Po co łączyć tabele?

Dane w relacyjnej bazie są podzielone na wiele tabel. Aby uzyskać pełny obraz, np. "który klient wypożyczył jaki samochód", trzeba połączyć tabele za pomocą kluczy.


Składnia złączenia

Sposób 1 – stary styl (przecinek w FROM + WHERE)

SELECT kolumny
FROM tabela1, tabela2
WHERE tabela1.klucz_obcy = tabela2.klucz_glowny;

Sposób 2 – nowoczesny JOIN

SELECT kolumny
FROM tabela1
JOIN tabela2 ON tabela1.klucz_obcy = tabela2.klucz_glowny;

Oba sposoby dają ten sam wynik. W kursie używamy obu.


1. Złączenie dwóch tabel

-- Wyświetl numery wypożyczeń i nazwiska klientów
SELECT WYPOZYCZENIA.NR_WYPOZYCZENIA, KLIENCI.NAZWISKO
FROM WYPOZYCZENIA, KLIENCI
WHERE WYPOZYCZENIA.NR_KLIENTA = KLIENCI.NR_KLIENTA;

-- Nowoczesny zapis z JOIN
SELECT w.NR_WYPOZYCZENIA, k.NAZWISKO
FROM WYPOZYCZENIA w
JOIN KLIENCI k ON w.NR_KLIENTA = k.NR_KLIENTA;
-- Marki samochodów, które zostały wypożyczone
SELECT MARKA
FROM SAMOCHODY, WYPOZYCZENIA
WHERE SAMOCHODY.NR_SAMOCHODU = WYPOZYCZENIA.NR_SAMOCHODU;

-- Bez powtórzeń i posortowane
SELECT DISTINCT MARKA
FROM SAMOCHODY, WYPOZYCZENIA
WHERE SAMOCHODY.NR_SAMOCHODU = WYPOZYCZENIA.NR_SAMOCHODU
ORDER BY MARKA;

2. Złączenie trzech tabel

-- Jakie samochody wypożyczył klient o nazwisku ADAMCZAK?
SELECT KLIENCI.NAZWISKO, SAMOCHODY.MARKA
FROM KLIENCI, WYPOZYCZENIA, SAMOCHODY
WHERE KLIENCI.NR_KLIENTA = WYPOZYCZENIA.NR_KLIENTA
AND KLIENCI.NAZWISKO = 'adamczak'
AND SAMOCHODY.NR_SAMOCHODU = WYPOZYCZENIA.NR_SAMOCHODU;
-- Kto (imię, nazwisko) i kiedy (data_wyp) wypożyczył jaki samochód (marka, typ)
SELECT k.IMIE, k.NAZWISKO, s.MARKA, s.TYP, w.DATA_WYP
FROM KLIENCI k, WYPOZYCZENIA w, SAMOCHODY s
WHERE k.NR_KLIENTA = w.NR_KLIENTA
AND s.NR_SAMOCHODU = w.NR_SAMOCHODU
ORDER BY w.DATA_WYP;

3. Tabela MIEJSCA – dwa złączenia z tą samą tabelą

Tabela WYPOZYCZENIA ma dwie kolumny odnoszące się do tabeli MIEJSCA:

  • NR_MIEJSCA_WYP – miejsce wypożyczenia
  • NR_MIEJSCA_ODD – miejsce oddania
-- Gdzie były wypożyczane samochody?
SELECT MIEJSCA.MIASTO
FROM MIEJSCA, WYPOZYCZENIA
WHERE WYPOZYCZENIA.NR_MIEJSCA_WYP = MIEJSCA.NR_MIEJSCA;

-- Bez powtórzeń
SELECT DISTINCT MIEJSCA.MIASTO
FROM MIEJSCA, WYPOZYCZENIA
WHERE WYPOZYCZENIA.NR_MIEJSCA_WYP = MIEJSCA.NR_MIEJSCA;

-- Gdzie były oddawane samochody?
SELECT DISTINCT MIEJSCA.MIASTO
FROM MIEJSCA, WYPOZYCZENIA
WHERE WYPOZYCZENIA.NR_MIEJSCA_ODD = MIEJSCA.NR_MIEJSCA;
-- Miasto wypożyczenia i miasto oddania w jednym zapytaniu
-- (użycie aliasów dla tej samej tabeli)
SELECT m_wyp.MIASTO AS MIASTO_WYPOZYCZENIA,
m_odd.MIASTO AS MIASTO_ODDANIA
FROM WYPOZYCZENIA w
JOIN MIEJSCA m_wyp ON w.NR_MIEJSCA_WYP = m_wyp.NR_MIEJSCA
JOIN MIEJSCA m_odd ON w.NR_MIEJSCA_ODD = m_odd.NR_MIEJSCA
WHERE w.NR_MIEJSCA_ODD IS NOT NULL;

4. Złączenie z warunkiem na tę samą tabelę

-- Wypożyczenia, gdzie ten sam pracownik wypożyczył i odebrał auto
SELECT *
FROM WYPOZYCZENIA
WHERE NR_PRACOW_WYP = NR_PRACOW_ODD;

-- Pokaż też dane pracownika
SELECT p.IMIE, p.NAZWISKO, w.NR_WYPOZYCZENIA
FROM WYPOZYCZENIA w
JOIN PRACOWNICY p ON w.NR_PRACOW_WYP = p.NR_PRACOWNIKA
WHERE w.NR_PRACOW_WYP = w.NR_PRACOW_ODD;

5. Pełne zapytanie łączące wszystkie tabele

-- Kompletny raport: klient, samochód, pracownik przyjmujący, miejsce
SELECT
k.IMIE AS KLIENT_IMIE,
k.NAZWISKO AS KLIENT_NAZWISKO,
s.MARKA,
s.TYP,
p.IMIE AS PRACOWNIK_IMIE,
p.NAZWISKO AS PRACOWNIK_NAZWISKO,
m.MIASTO AS MIASTO_WYPOZYCZENIA,
w.DATA_WYP,
w.DATA_ODD
FROM WYPOZYCZENIA w
JOIN KLIENCI k ON w.NR_KLIENTA = k.NR_KLIENTA
JOIN SAMOCHODY s ON w.NR_SAMOCHODU = s.NR_SAMOCHODU
JOIN PRACOWNICY p ON w.NR_PRACOW_WYP = p.NR_PRACOWNIKA
JOIN MIEJSCA m ON w.NR_MIEJSCA_WYP = m.NR_MIEJSCA
ORDER BY w.DATA_WYP;

Ćwiczenia

  1. Wyświetl imiona i nazwiska klientów wraz z marką wypożyczonego samochodu.
  2. Wyświetl unikalne nazwiska klientów, którzy wypożyczali samochody marki Mercedes.
  3. Wyświetl imię i nazwisko pracownika, który obsłużył wypożyczenie nr 00000006.
  4. Wyświetl wszystkie wypożyczenia z miastem wypożyczenia i miastem oddania.
  5. Wyświetl klientów, którzy wypożyczali samochody w Krakowie.
Rozwiązania
-- 1
SELECT k.IMIE, k.NAZWISKO, s.MARKA
FROM KLIENCI k, WYPOZYCZENIA w, SAMOCHODY s
WHERE k.NR_KLIENTA = w.NR_KLIENTA
AND s.NR_SAMOCHODU = w.NR_SAMOCHODU;

-- 2
SELECT DISTINCT k.IMIE, k.NAZWISKO
FROM KLIENCI k, WYPOZYCZENIA w, SAMOCHODY s
WHERE k.NR_KLIENTA = w.NR_KLIENTA
AND s.NR_SAMOCHODU = w.NR_SAMOCHODU
AND s.MARKA = 'Mercedes';

-- 3
SELECT p.IMIE, p.NAZWISKO
FROM PRACOWNICY p, WYPOZYCZENIA w
WHERE w.NR_PRACOW_WYP = p.NR_PRACOWNIKA
AND w.NR_WYPOZYCZENIA = '00000006';

-- 4
SELECT w.NR_WYPOZYCZENIA, mw.MIASTO AS wyp, mo.MIASTO AS odd
FROM WYPOZYCZENIA w
JOIN MIEJSCA mw ON w.NR_MIEJSCA_WYP = mw.NR_MIEJSCA
LEFT JOIN MIEJSCA mo ON w.NR_MIEJSCA_ODD = mo.NR_MIEJSCA;

-- 5
SELECT DISTINCT k.IMIE, k.NAZWISKO
FROM KLIENCI k
JOIN WYPOZYCZENIA w ON k.NR_KLIENTA = w.NR_KLIENTA
JOIN MIEJSCA m ON w.NR_MIEJSCA_WYP = m.NR_MIEJSCA
WHERE m.MIASTO = 'Krakow';

Poprzedni moduł: Filtrowanie danych Następny moduł: Funkcje agregujące