INF.03 · Bazy danych i SQL

Sklep komputerowy, część 5: zamówienia i zapytania JOIN

Dotąd klienci i produkty istniały osobno: nikt jeszcze niczego nie kupił. Teraz łączysz je piątą tabelą, Zamowienia, i uczysz się odpowiadać na pytania, które wymagają danych z kilku tabel naraz. To też pierwsze zadanie, w którym LEFT JOIN rzeczywiście zmienia wynik.

  • około 50 minut
  • CREATE TABLE · INSERT · JOIN · LEFT JOIN
  • 5 tabel razem

Po tej lekcji: dodasz tabelę z kluczami obcymi, wypełnisz ją i odpowiesz zapytaniami łączącymi trzy tabele, w tym takimi, które pokazują brak dopasowania.

1 · Sytuacja

Tabela Zamowienia i piętnaście zamówień

Najpierw dodaj tabelę Zamowienia (struktura poniżej), potem wpisz piętnaście zamówień z tabeli danych. Sprawdź SELECT * FROM Zamowienia; przed pierwszym JOIN. Złączenia buduj stopniowo: najpierw dwie tabele, a dopiero potem trzecia.

W zapytaniach z LEFT JOIN pamiętaj o warunku IS NULL, żeby wyłowić brakujące dopasowania.

Tabela Zamowienia do utworzenia

KolumnaWymagania
id_zamowieniaklucz główny, numerowany automatycznie
id_klientaliczba całkowita, obowiązkowa, klucz obcy do Klienci
id_produktuliczba całkowita, obowiązkowa, klucz obcy do Produkty
iloscliczba całkowita, obowiązkowa, większa od 0
data_zamowieniadata, obowiązkowa
Dwa klucze obce robią z tej tabeli tabelę pośredniczącą relacji N:M między klientami a produktami.

Dane do wpisania (15 zamówień)

id_zamowieniaid_klientaid_produktuiloscdata_zamowienia
11112026-01-05
21722026-01-05
32412026-01-12
421012026-01-12
53212026-01-20
63822026-01-20
741322026-02-02
84512026-02-02
951132026-02-10
1051412026-02-14
116312026-02-18
1261212026-02-18
137612026-03-01
147742026-03-01
1511312026-03-03
Olga Mazur (klient 8) nie złożyła żadnego zamówienia, a produkty 9 i 15 nigdy nie zostały zamówione. Nie jest to błąd w danych.

2 · Do wykonania

Zadania do wykonania

  1. Sprawdź liczbę zamówień: SELECT COUNT(*) FROM Zamowienia;
    Oczekiwany wynik1 wierszpierwszy wiersz: 15
  2. Pokaż imię, nazwisko klienta, nazwę produktu, ilość i datę dla każdego zamówienia (trzy tabele, bez samych numerów).
    Oczekiwany wynik15 wierszy
  3. Pokaż łączną kwotę wydaną przez każdego klienta (nazwisko i suma ilość razy cena) od największej kwoty.
    Oczekiwany wynik7 wierszypierwszy wiersz: Kamiński · 6595.00
  4. Znajdź produkty, które nigdy nie zostały zamówione. Użyj LEFT JOIN i IS NULL.
    Oczekiwany wynik2 wiersze
  5. Znajdź klienta, który wydał w sklepie najwięcej pieniędzy (jeden wiersz).
    Oczekiwany wynik1 wierszpierwszy wiersz: Kamiński · 6595.00
  6. Pokaż wszystkich klientów razem z liczbą złożonych zamówień, także tych, którzy nic nie zamówili (liczba 0).
    Oczekiwany wynik8 wierszy
  7. Pokaż wszystkie produkty z liczbą zamówień, w których występują (COUNT), także te, których nikt nie zamówił (liczba 0). Posortuj rosnąco po liczbie zamówień, a przy remisie po nazwie produktu.
    Oczekiwany wynik15 wierszypierwszy wiersz: Monitor 32" 4K · 0

3 · Sprawdź się

Czy Twoje wyniki się zgadzają?

To szybka kontrola, a nie ocena. Liczba wierszy jest pierwszym sygnałem, że warunek albo złączenie działa tak, jak trzeba.

Ta interakcja wymaga włączonego JavaScriptu.

4 · Zanim się pomylisz

Cztery pomyłki w złączeniach

Rozwiń każdą z nich.

INNER JOIN tam, gdzie potrzebny LEFT JOIN
Tak nie
SELECT p.nazwa FROM Produkty p
JOIN Zamowienia z ON z.id_produktu = p.id_produktu
WHERE z.id_zamowienia IS NULL;

Pusty wynik. INNER JOIN zostawia tylko pary dopasowane, więc produkty bez zamówień znikają, zanim IS NULL je zobaczy.

Tak
SELECT p.nazwa FROM Produkty p
LEFT JOIN Zamowienia z ON z.id_produktu = p.id_produktu
WHERE z.id_zamowienia IS NULL;

Brakujące dopasowania pokazuje tylko LEFT JOIN.

COUNT(*) przy LEFT JOIN
Tak nie
SELECT k.nazwisko, COUNT(*)
FROM Klienci k LEFT JOIN Zamowienia z ON z.id_klienta = k.id_klienta
GROUP BY k.id_klienta;

Klient bez zamówień ma liczbę 1, bo jego wiersz z NULL też jest liczony.

Tak
SELECT k.nazwisko, COUNT(z.id_zamowienia)
FROM ...

COUNT(kolumna z drugiej tabeli) pomija NULL, więc dla Olgi daje 0.

Zła kolejność w FROM przy LEFT JOIN
Tak nie
FROM Zamowienia z LEFT JOIN Klienci k ON ...

Zachowujesz wszystkie zamówienia, a chciałeś wszystkich klientów.

Tak
FROM Klienci k LEFT JOIN Zamowienia z ON ...

Zachowywana jest tabela po lewej stronie zapisu.

Brak ON
Tak nie
FROM Zamowienia z JOIN Klienci k;

Powstaje iloczyn kartezjański: 15 × 8 = 120 wierszy zamiast 15.

Tak
FROM Zamowienia z JOIN Klienci k ON z.id_klienta = k.id_klienta;

Zawsze porównuj liczbę wierszy wyniku z liczbą zamówień.

5 · Sprawdź sam siebie

Zanim oddasz pracę

Ta lista odpowiada temu, co sprawdza komisja egzaminacyjna: poprawną bazę, poprawne wyniki i dokumentację.

Podsumowanie

Co warto zapamiętać

  1. Tabela pośrednicząca z dwoma kluczami obcymi łączy klientów z produktami.
  2. INNER JOIN pomija wiersze bez pary, a LEFT JOIN je zachowuje (z NULL).
  3. Brakujące dopasowania znajdziesz przez LEFT JOIN ... WHERE ... IS NULL.
  4. Przy LEFT JOIN licz COUNT(kolumna z prawej tabeli), a nie COUNT(*).

Dalej na swoim koncie

Rozgrzewki, quiz i zadania są w biurku ucznia.

Teoria jest otwarta dla wszystkich. Żeby rozwiązywać zadania, zapisywać szkice i widzieć swój postęp, zaloguj się.

Zaloguj się →
Źródła i dalsza nauka