Zadanie 15 (egzaminacyjne): Szkoła językowa — wielotabelowe zestawienia
Trudny / egzaminacyjnyPo co się tego uczymy?
Kolumna typu BOOLEAN (opłacone/nieopłacone) dodaje nowy wymiar filtrowania — to częsty element prawdziwych baz danych, z którym warto się oswoić.
Treść zadania
Scenariusz: Szkoła językowa zarządza kursami, lektorami i zapisami uczniów.
Krok 1: Zaimportuj bazę z kodu poniżej.
Krok 2 — zapytania:
1. Pokaż wszystkie kursy razem z imieniem i nazwiskiem prowadzącego lektora.
2. Pokaż uczniów, którzy zapisali się na kurs, ale jeszcze NIE zapłacili (oplacone = FALSE).
3. Policz, ilu uczniów zapisało się na każdy kurs.
4. Oblicz łączny przychód szkoły z KURSÓW JUŻ OPŁACONYCH (JOIN + WHERE + SUM).
5. Znajdź lektora, którego kursy cieszą się największą łączną liczbą zapisów.
6. Pokaż uczniów zapisanych na więcej niż jeden kurs (GROUP BY + HAVING COUNT > 1).
Jak zabrać się do zadania
1. Pobierz plik .sql przyciskiem w sekcji "Rozwiązanie" na dole strony.
2. Uruchom Apache i MySQL w XAMPP Control Panel.
3. W phpMyAdmin utwórz pustą bazę danych o podanej nazwie.
4. Kliknij w nazwę tej bazy w lewym panelu, żeby ją wybrać jako aktywną.
5. Przejdź do zakładki "Importuj" (nie "SQL"), kliknij "Wybierz plik", wskaż pobrany plik i kliknij "Wykonaj".
6. Dopiero po potwierdzonym imporcie przejdź do wykonywania zapytań z listy.
Jak powinien wyglądać efekt
Zapytanie 2 (niezapłacone zapisy) powinno zwrócić tylko część wszystkich zapisów — sprawdź w danych startowych, które mają oplacone = FALSE. Zapytanie 6 (uczniowie na więcej niż jednym kursie) powinno zwrócić tylko tych, którzy naprawdę pojawiają się więcej niż raz w tabeli Zapisy.
Typowe problemy i jak sobie z nimi poradzić
W zapytaniu 4 warunek WHERE oplacone = TRUE musi zostać dodany PRZED grupowaniem/sumowaniem, żeby nieopłacone zapisy w ogóle nie weszły do sumy.
Nawiązanie do egzaminu zawodowego
To zadanie w konwencji egzaminacyjnej ćwiczy jednostkę INF.03.4 jako całość — dokładnie tak wygląda część "Operacje na bazie danych" prawdziwego arkusza części praktycznej egzaminu INF.03.
Kryteria sukcesu — sprawdź, czy wykonałeś zadanie poprawnie
Po wykonaniu zadania sprawdź, czy:
1. zapytanie 2 pokazuje tylko zapisy z oplacone = FALSE,
2. zapytanie 4 liczy przychód WYŁĄCZNIE z opłaconych kursów,
3. zapytanie 6 (uczniowie na więcej niż 1 kursie) używa GROUP BY i HAVING COUNT > 1,
4. rozumiesz różnicę między kolumną typu BOOLEAN a tekstową przy filtrowaniu.
Rozwiązanie — gotowa baza danych
Pobierz plik i zaimportuj go w phpMyAdmin przez zakładkę „Importuj” — dokładnie tak, jak wygląda to na prawdziwym egzaminie. Blok kodu poniżej to podgląd zawartości tego samego pliku, przydatny do sprawdzenia struktury bez otwierania go osobno.
CREATE DATABASE IF NOT EXISTS szkola_jezykowa;
USE szkola_jezykowa;
CREATE TABLE Lektorzy (
id_lektora INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50), nazwisko VARCHAR(50), jezyk VARCHAR(30)
);
CREATE TABLE Kursy (
id_kursu INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(80), poziom VARCHAR(10), id_lektora INT, cena DECIMAL(7,2),
FOREIGN KEY (id_lektora) REFERENCES Lektorzy(id_lektora)
);
CREATE TABLE Uczniowie (
id_ucznia INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50), nazwisko VARCHAR(50), email VARCHAR(100) UNIQUE
);
CREATE TABLE Zapisy (
id_ucznia INT, id_kursu INT, data_zapisu DATE, oplacone BOOLEAN DEFAULT FALSE,
PRIMARY KEY (id_ucznia, id_kursu),
FOREIGN KEY (id_ucznia) REFERENCES Uczniowie(id_ucznia),
FOREIGN KEY (id_kursu) REFERENCES Kursy(id_kursu)
);
INSERT INTO Lektorzy (imie, nazwisko, jezyk) VALUES
('John', 'Smith', 'angielski'), ('Marie', 'Dubois', 'francuski'),
('Hans', 'Weber', 'niemiecki'), ('Anna', 'Kowalczyk', 'angielski');
INSERT INTO Kursy (nazwa, poziom, id_lektora, cena) VALUES
('Angielski dla początkujących', 'A1', 1, 450.00),
('Angielski konwersacje', 'B2', 4, 600.00),
('Francuski od podstaw', 'A1', 2, 480.00),
('Niemiecki biznesowy', 'B1', 3, 650.00),
('Angielski egzaminacyjny', 'C1', 1, 700.00);
INSERT INTO Uczniowie (imie, nazwisko, email) VALUES
('Natalia', 'Sobczak', 'n.sobczak@gmail.com'), ('Oskar', 'Kaczmarczyk', 'o.kaczmarczyk@wp.pl'),
('Patrycja', 'Wieczorkowska', 'p.wieczorkowska@gmail.com'), ('Radosław', 'Baranowski', 'r.baranowski@onet.pl'),
('Sylwia', 'Kubiak', 's.kubiak@gmail.com');
INSERT INTO Zapisy (id_ucznia, id_kursu, data_zapisu, oplacone) VALUES
(1,1,'2026-02-01',TRUE), (1,2,'2026-02-15',FALSE), (2,3,'2026-02-02',TRUE),
(3,1,'2026-02-03',TRUE), (3,5,'2026-02-20',TRUE), (4,4,'2026-02-05',FALSE),
(5,2,'2026-02-06',TRUE), (2,1,'2026-02-07',TRUE);