Najpierw utwórz bazę danych sklep i tabele, a potem dane testowe.
Wykonaj kod w phpMyAdmin → baza sklep → zakładka SQL.
Zadanie: Utwórz bazę danych sklep i tabelę klienci.
CREATE DATABASE IF NOT EXISTS sklep
CHARACTER SET utf8mb4
COLLATE utf8mb4_polish_ci;
USE sklep;
CREATE TABLE IF NOT EXISTS klienci (
id_klienta INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50),
nazwisko VARCHAR(50),
email VARCHAR(100),
telefon VARCHAR(20)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_polish_ci;
AUTO_INCREMENT automatycznie nadaje kolejne ID, a ustawienie utf8mb4 i polskiej kolacji zapewnia poprawne kodowanie i sortowanie. [web:58]
Zadanie: Utwórz tabelę zamowienia z kluczem obcym do klienci.
CREATE TABLE IF NOT EXISTS zamowienia (
id_zamowienia INT AUTO_INCREMENT PRIMARY KEY,
id_klienta INT,
data_zamowienia DATE,
wartosc_zamowienia DECIMAL(10,2),
status ENUM('Nowe', 'Realizacja', 'Zakonczone') DEFAULT 'Nowe',
FOREIGN KEY (id_klienta) REFERENCES klienci(id_klienta)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_polish_ci;
ENUM wymusza jedną z predefiniowanych wartości, a klucz obcy pilnuje, by zamówienie zawsze wskazywało istniejącego klienta. [web:75]
Zadanie: Dodaj klientów i zamówienia.
INSERT INTO klienci (imie, nazwisko, email, telefon) VALUES
('Jan', 'Kowalski', 'jan@test.pl', '500100200'),
('Anna', 'Nowak', 'anna@test.pl', '501202303'),
('Piotr', 'Zajac', 'piotr@test.pl', '503404505');
INSERT INTO zamowienia (id_klienta, data_zamowienia, wartosc_zamowienia, status) VALUES
(1, '2023-12-15', 120.50, 'Zakonczone'),
(1, '2024-03-20', 650.00, 'Realizacja'),
(2, '2024-01-05', 45.99, 'Zakonczone'),
(3, '2024-05-01', 890.00, 'Nowe');
id_klienta muszą istnieć w tabeli klienci, inaczej klucz obcy zablokuje wstawienie.
Zadanie: Dodaj adres do klientów, upewnij się, że tabela zamowienia ma kolumnę status, wydłuż telefon.
ALTER TABLE klienci
ADD COLUMN adres VARCHAR(255);
-- jeśli status już jest, ten ALTER można pominąć
-- ALTER TABLE zamowienia
-- ADD COLUMN status ENUM('Nowe', 'Realizacja', 'Zakonczone') DEFAULT 'Nowe';
ALTER TABLE klienci
MODIFY COLUMN telefon VARCHAR(20);
ALTER TABLE pozwala rozwijać schemat bez kasowania danych.
Zadanie: Usuń tabelę zamowienia i stwórz ją ponownie z kolumną metoda_platnosci.
DROP TABLE IF EXISTS zamowienia;
CREATE TABLE zamowienia (
id_zamowienia INT AUTO_INCREMENT PRIMARY KEY,
id_klienta INT,
data_zamowienia DATE,
wartosc_zamowienia DECIMAL(10,2),
metoda_platnosci ENUM('Gotowka', 'Karta', 'Przelew'),
status ENUM('Nowe', 'Realizacja', 'Zakonczone') DEFAULT 'Nowe',
FOREIGN KEY (id_klienta) REFERENCES klienci(id_klienta)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_polish_ci;
DROP TABLE trzeba ponownie wstawić dane testowe do zamowienia, jeśli chcesz używać późniejszych ćwiczeń.
Zadanie: Utwórz indeks po emailu i policz wydatki klientów.
CREATE INDEX idx_email ON klienci(email);
SELECT id_klienta,
SUM(wartosc_zamowienia) AS suma_wydatkow
FROM zamowienia
GROUP BY id_klienta
ORDER BY suma_wydatkow DESC;
email przyspiesza wyszukiwanie, a kombinacja GROUP BY + SUM() daje raport wydatków.
Zadanie: Stwórz tabelę produktów.
CREATE TABLE IF NOT EXISTS produkty (
id_produktu INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(100),
cena DECIMAL(10,2),
kategoria VARCHAR(50)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_polish_ci;
Zadanie: Tabela łącząca zamówienia z produktami.
CREATE TABLE IF NOT EXISTS szczegoly_zamowienia (
id_szczegolu INT AUTO_INCREMENT PRIMARY KEY,
id_zamowienia INT,
id_produktu INT,
ilosc INT,
FOREIGN KEY (id_zamowienia) REFERENCES zamowienia(id_zamowienia),
FOREIGN KEY (id_produktu) REFERENCES produkty(id_produktu)
) ENGINE=InnoDB
DEFAULT CHARSET=utf8mb4
COLLATE=utf8mb4_polish_ci;
Zadanie: Dodaj kolumnę vip dla klientów.
ALTER TABLE klienci
ADD COLUMN vip BOOLEAN DEFAULT 0;
BOOLEAN to alias TINYINT(1), gdzie 0 oznacza false, a 1 true. [web:49][web:46]
Zadanie: Ustaw status = 'Zakonczone' dla zamówień sprzed 2024‑01‑01.
UPDATE zamowienia
SET status = 'Zakonczone'
WHERE data_zamowienia < '2024-01-01';
Zadanie: Usuń klientów, którzy nie występują w tabeli zamowienia.
DELETE FROM klienci
WHERE id_klienta NOT IN (
SELECT DISTINCT id_klienta FROM zamowienia
);
Zadanie: Stwórz widok dla zamówień, które nie są zakończone.
CREATE OR REPLACE VIEW aktywne_zamowienia AS
SELECT *
FROM zamowienia
WHERE status <> 'Zakonczone';
SELECT * FROM aktywne_zamowienia;
Zadanie: Policz liczbę zamówień każdego klienta.
SELECT id_klienta,
COUNT(*) AS liczba_zamowien
FROM zamowienia
GROUP BY id_klienta;
Zadanie: Dodaj kolumnę rabat do klienci.
ALTER TABLE klienci
ADD COLUMN rabat DECIMAL(5,2) DEFAULT 0.00;
Zadanie: Procedura przyjmująca ID klienta i wartość zamówienia.
DELIMITER //
CREATE PROCEDURE DodajZamowienie(
IN klient_id INT,
IN wartosc DECIMAL(10,2)
)
BEGIN
INSERT INTO zamowienia (id_klienta, data_zamowienia, wartosc_zamowienia, status)
VALUES (klient_id, NOW(), wartosc, 'Nowe');
END //
DELIMITER ;
CALL DodajZamowienie(1, 75.99); – data ustawiana jest funkcją NOW().
Zadanie: Jeśli wartość zamówienia przekroczy 500 zł, ustaw status zamówienia na specjalny status, np. 'VIP' (rozszerzamy ENUM).
-- najpierw rozszerz ENUM o 'VIP', jeśli trzeba:
ALTER TABLE zamowienia
MODIFY COLUMN status ENUM('Nowe', 'Realizacja', 'Zakonczone', 'VIP')
DEFAULT 'Nowe';
DELIMITER //
CREATE TRIGGER AktualizujStatusVIP
BEFORE INSERT ON zamowienia
FOR EACH ROW
BEGIN
IF NEW.wartosc_zamowienia > 500 THEN
SET NEW.status = 'VIP';
END IF;
END //
DELIMITER ;
BEFORE INSERT podmienia status, zanim rekord zostanie zapisany – każde nowe duże zamówienie od razu otrzyma status VIP.