Zadanie 13 (egzaminacyjne): Restauracja Smakosz — JOIN i HAVING
Trudny / egzaminacyjnyPo co się tego uczymy?
Ten zestaw wymaga łączenia czterech tabel naraz i filtrowania wyników po agregacji (HAVING) — to poziom, jakiego można się spodziewać w trudniejszej części egzaminu.
Treść zadania
Scenariusz: Restauracja Smakosz rejestruje zamówienia przypisane do stolików.
Krok 1: Zaimportuj bazę z kodu poniżej.
Krok 2 — zapytania:
1. Pokaż wszystkie zamówienia z 1 marca 2026 razem z nazwą dania i numerem stolika.
2. Policz łączny utarg (cena × ilość) z każdego stolika tego wieczoru.
3. Znajdź stoliki, których łączny rachunek przekroczył 150 zł (GROUP BY + HAVING).
4. Pokaż najczęściej zamawiane danie (COUNT + ORDER BY + LIMIT).
5. Pokaż dania z kategorii "Dania główne", które NIE zostały zamówione tego wieczoru wcale (LEFT JOIN).
6. Oblicz średnią wartość zamówienia na stolik.
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 3 (stoliki z rachunkiem >150 zł) powinno zwrócić tylko część z pięciu stolików — nie wszystkie miały tego wieczoru na tyle duże zamówienia. Zapytanie 5 (dania z kategorii "Dania główne" bez zamówień) sprawdza, czy pamiętasz o LEFT JOIN zamiast INNER JOIN.
Typowe problemy i jak sobie z nimi poradzić
W zapytaniu 3 pamiętaj, że warunek na WYNIK sumowania ("powyżej 150 zł") idzie do HAVING, a nie do WHERE — WHERE nie "widzi" jeszcze policzonej 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 (import/utworzenie bazy, seria zapytań SQL do wykonania i udokumentowania zrzutami ekranu).
Kryteria sukcesu — sprawdź, czy wykonałeś zadanie poprawnie
Po wykonaniu zadania sprawdź, czy:
1. zapytanie 3 używa HAVING (nie WHERE) do filtrowania sumy rachunku,
2. zapytanie 4 poprawnie wskazuje najczęściej zamawiane danie,
3. zapytanie 5 (dania niezamówione) używa LEFT JOIN,
4. rozumiesz, dlaczego wynik zapytania 6 (średnia na stolik) może być liczbą niecałkowitą.
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 restauracja_smakosz;
USE restauracja_smakosz;
CREATE TABLE KategorieDan (
id_kategorii INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(50)
);
CREATE TABLE Dania (
id_dania INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(100), cena DECIMAL(6,2), id_kategorii INT,
FOREIGN KEY (id_kategorii) REFERENCES KategorieDan(id_kategorii)
);
CREATE TABLE Stoliki (
id_stolika INT AUTO_INCREMENT PRIMARY KEY,
numer INT, liczba_miejsc INT
);
CREATE TABLE Zamowienia (
id_zamowienia INT AUTO_INCREMENT PRIMARY KEY,
id_stolika INT, id_dania INT, ilosc INT, data_zamowienia DATETIME,
FOREIGN KEY (id_stolika) REFERENCES Stoliki(id_stolika),
FOREIGN KEY (id_dania) REFERENCES Dania(id_dania)
);
INSERT INTO KategorieDan (nazwa) VALUES ('Przystawki'),('Zupy'),('Dania główne'),('Desery'),('Napoje');
INSERT INTO Dania (nazwa, cena, id_kategorii) VALUES
('Carpaccio z buraka', 24.00, 1), ('Krem z pomidorów', 18.00, 2),
('Stek z polędwicy', 68.00, 3), ('Risotto z kurczakiem', 42.00, 3),
('Tiramisu', 22.00, 4), ('Woda mineralna', 8.00, 5),
('Sernik', 20.00, 4), ('Pierogi ruskie', 32.00, 3);
INSERT INTO Stoliki (numer, liczba_miejsc) VALUES (1,2),(2,4),(3,4),(4,6),(5,2);
INSERT INTO Zamowienia (id_stolika, id_dania, ilosc, data_zamowienia) VALUES
(1,3,1,'2026-03-01 19:00'), (1,6,2,'2026-03-01 19:00'),
(2,4,2,'2026-03-01 19:30'), (2,5,2,'2026-03-01 20:15'),
(3,8,4,'2026-03-01 20:00'), (4,3,3,'2026-03-01 20:30'),
(4,7,3,'2026-03-01 21:15'), (5,2,1,'2026-03-01 18:45'),
(5,1,1,'2026-03-01 18:45'), (2,6,4,'2026-03-01 19:30');