Wyobraź sobie sklep muzyczny.
Masz trzy półki:
- na jednej są klienci,
- na drugiej produkty,
- a na trzeciej zamówienia.
Każda półka (czyli tabela) zawiera inne informacje, ale wszystkie są ze sobą powiązane.
Żeby dowiedzieć się, kto co kupił, musimy połączyć dane z kilku tabel.
Na tym właśnie polegają relacje i łączenie tabel (JOIN).
1. Czym są relacje w bazie danych?
Relacje pokazują, jak tabele są ze sobą powiązane.
To tak, jakbyś miał trzy kartoteki połączone nitkami — klienta, produkt i zamówienie.
W relacyjnej bazie danych tabele łączą się ze sobą za pomocą kluczy:
- klucz główny (PRIMARY KEY) – jednoznacznie identyfikuje każdy rekord,
- klucz obcy (FOREIGN KEY) – wskazuje na rekord w innej tabeli.
2. Przykład – baza sklep_muzyczny
W naszym przykładzie mamy trzy tabele:
CREATE DATABASE sklep_muzyczny;
USE sklep_muzyczny;
Tabela Klienci
CREATE TABLE Klienci (
id_klienta INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50) NOT NULL,
nazwisko VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);
Tabela Produkty
CREATE TABLE Produkty (
id_produktu INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(100) NOT NULL,
cena DECIMAL(10, 2) NOT NULL,
kategoria VARCHAR(50) NOT NULL
);
Tabela Zamowienia
CREATE TABLE Zamowienia (
id_zamowienia INT AUTO_INCREMENT PRIMARY KEY,
id_klienta INT NOT NULL,
id_produktu INT NOT NULL,
ilosc INT NOT NULL,
data_zamowienia DATE NOT NULL,
FOREIGN KEY (id_klienta) REFERENCES Klienci(id_klienta),
FOREIGN KEY (id_produktu) REFERENCES Produkty(id_produktu)
);
Zauważ, że tabela Zamowienia łączy klientów i produkty przez klucze obce (FOREIGN KEY).
Każde zamówienie mówi nam, który klient kupił jaki produkt i kiedy.
3. Wstawianie przykładowych danych
-- Klienci
INSERT INTO Klienci (imie, nazwisko, email) VALUES
('Jan', 'Kowalski', 'jan.kowalski@example.com'),
('Anna', 'Nowak', 'anna.nowak@example.com'),
('Marek', 'Wiśniewski', 'marek.wisniewski@example.com');
-- Produkty
INSERT INTO Produkty (nazwa, cena, kategoria) VALUES
('Gitara akustyczna', 499.99, 'Instrumenty'),
('Keyboard Yamaha', 1299.99, 'Instrumenty'),
('Mikrofon Shure', 299.99, 'Akcesoria'),
('Słuchawki Sony', 199.99, 'Akcesoria'),
('Struny do gitary', 39.99, 'Akcesoria');
-- Zamówienia
INSERT INTO Zamowienia (id_klienta, id_produktu, ilosc, data_zamowienia) VALUES
(1, 1, 1, '2025-01-01'),
(1, 5, 2, '2025-01-01'),
(2, 2, 1, '2025-01-02'),
(2, 4, 1, '2025-01-02'),
(3, 3, 1, '2025-01-03');
4. Typy relacji
W bazach danych wyróżniamy trzy główne typy relacji:
| Typ relacji | Opis | Przykład |
|---|---|---|
| 1:1 (jeden do jednego) | jeden rekord w tabeli A odpowiada jednemu w tabeli B | np. pracownik ↔ legitymacja |
| 1:N (jeden do wielu) | jeden rekord w tabeli A może mieć wiele powiązanych rekordów w tabeli B | klient ↔ zamówienia |
| N:M (wiele do wielu) | wiele rekordów w tabeli A może mieć wiele powiązań w tabeli B | uczniowie ↔ przedmioty (z tabelą pośredniczącą oceny) |
W naszym sklepie występuje relacja 1:N:
- jeden klient może złożyć wiele zamówień,
- ale jedno zamówienie należy do jednego klienta.
5. Łączenie tabel – JOIN
Aby wyświetlić dane z kilku tabel naraz, używamy JOIN.
To polecenie pozwala połączyć tabele po wspólnych kolumnach.
a) INNER JOIN – dane, które występują w obu tabelach
Pokaż, kto co kupił:
SELECT Klienci.imie, Klienci.nazwisko, Produkty.nazwa, Zamowienia.ilosc
FROM Zamowienia
INNER JOIN Klienci ON Zamowienia.id_klienta = Klienci.id_klienta
INNER JOIN Produkty ON Zamowienia.id_produktu = Produkty.id_produktu;
Wynik:
| imie | nazwisko | nazwa | ilosc |
|---|---|---|---|
| Jan | Kowalski | Gitara akustyczna | 1 |
| Jan | Kowalski | Struny do gitary | 2 |
| Anna | Nowak | Keyboard Yamaha | 1 |
| Anna | Nowak | Słuchawki Sony | 1 |
| Marek | Wiśniewski | Mikrofon Shure | 1 |
b) LEFT JOIN – wszystkie rekordy z lewej tabeli (nawet jeśli nie mają dopasowania)
Pokaż wszystkich klientów, nawet tych, którzy nie złożyli żadnego zamówienia:
SELECT Klienci.imie, Klienci.nazwisko, Produkty.nazwa
FROM Klienci
LEFT JOIN Zamowienia ON Klienci.id_klienta = Zamowienia.id_klienta
LEFT JOIN Produkty ON Zamowienia.id_produktu = Produkty.id_produktu;
Jeśli jakiś klient nic nie kupił, kolumna nazwa będzie pusta (NULL).
c) RIGHT JOIN – wszystkie rekordy z prawej tabeli
Pokaż wszystkie produkty, nawet jeśli nikt ich nie kupił:
SELECT Produkty.nazwa, Produkty.cena, Klienci.imie, Klienci.nazwisko
FROM Produkty
RIGHT JOIN Zamowienia ON Produkty.id_produktu = Zamowienia.id_produktu
RIGHT JOIN Klienci ON Zamowienia.id_klienta = Klienci.id_klienta;
d) CROSS JOIN – połączenie wszystkich rekordów z obu tabel (uwaga!)
Rzadko używane – tworzy każdą możliwą kombinację:
SELECT Klienci.imie, Produkty.nazwa
FROM Klienci
CROSS JOIN Produkty;
Jeśli jest 3 klientów i 5 produktów, wynik da 15 wierszy.
6. Aliasowanie tabel
Żeby zapytania były krótsze i czytelniejsze, można nadać tabelom aliasy:
SELECT k.imie, k.nazwisko, p.nazwa, z.ilosc
FROM Zamowienia z
JOIN Klienci k ON z.id_klienta = k.id_klienta
JOIN Produkty p ON z.id_produktu = p.id_produktu;
7. Zadania praktyczne
Zadanie 1 – proste połączenie
Wyświetl listę wszystkich klientów i produkty, które kupili (imie, nazwisko, nazwa produktu, data zamówienia).
Zadanie 2 – brak zamówień
Używając LEFT JOIN, pokaż wszystkich klientów, nawet tych, którzy nie złożyli żadnego zamówienia.
Dla takich klientów kolumna nazwa powinna mieć wartość NULL.
Zadanie 3 – najdroższe zakupy
Wyświetl klientów i produkty posortowane malejąco po cenie produktu (ORDER BY cena DESC).
Zadanie 4 – zliczanie zamówień (dla chętnych)
Pokaż każdego klienta i liczbę jego zamówień:
SELECT k.imie, k.nazwisko, COUNT(z.id_zamowienia) AS liczba_zamowien
FROM Klienci k
LEFT JOIN Zamowienia z ON k.id_klienta = z.id_klienta
GROUP BY k.imie, k.nazwisko;
Podsumowanie
| Typ relacji / JOIN | Co robi | Kiedy używać |
|---|---|---|
| INNER JOIN | zwraca tylko powiązane rekordy | gdy interesują nas tylko dopasowania |
| LEFT JOIN | zwraca wszystkie rekordy z lewej tabeli | gdy chcemy zobaczyć również brakujące dane |
| RIGHT JOIN | zwraca wszystkie rekordy z prawej tabeli | rzadziej używany, działa jak LEFT w drugą stronę |
| CROSS JOIN | tworzy każdą możliwą kombinację | głównie do testów lub specjalnych analiz |
| FOREIGN KEY | łączy dane między tabelami | zapewnia spójność i integralność danych |
Relacje i łączenie tabel to serce relacyjnych baz danych.
Dzięki nim możesz łączyć różne informacje i uzyskać pełny obraz danych – kto kupił, co kupił i kiedy.
Bez tego SQL byłby tylko zbiorem osobnych tabel, a nie prawdziwym systemem informacji.

