Polecenie: Upewnij się, że masz zainstalowany XAMPP (lub inny pakiet: Laragon, WAMP) i uruchom moduły Apache oraz MySQL.
Polecenie: Otwórz http://localhost/phpmyadmin/, przejdź do zakładki SQL i wykonaj poniższy kod, aby utworzyć bazę ksiegarnia i tabele.
-- 1. Utworzenie bazy (UTF-8, polskie znaki)
CREATE DATABASE IF NOT EXISTS ksiegarnia
CHARACTER SET utf8mb4
COLLATE utf8mb4_polish_ci;
USE ksiegarnia;
-- 2. Tabela Ksiazki (klucz główny, logika biznesowa)
CREATE TABLE IF NOT EXISTS Ksiazki (
ID INT PRIMARY KEY AUTO_INCREMENT,
Tytul VARCHAR(255) NOT NULL,
Autor VARCHAR(100),
Cena DECIMAL(10, 2) NOT NULL,
Dostepna BOOLEAN DEFAULT TRUE,
DataWydania DATE
);
-- 3. Tabela Uzytkownicy (klucz główny, unikalny email)
CREATE TABLE IF NOT EXISTS Uzytkownicy (
ID INT PRIMARY KEY AUTO_INCREMENT,
Imie VARCHAR(50) NOT NULL,
Nazwisko VARCHAR(50) NOT NULL,
Email VARCHAR(100) UNIQUE,
DataRejestracji TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 4. Tabela Zamowienia (relacja N:1 z Uzytkownicy)
CREATE TABLE IF NOT EXISTS Zamowienia (
ID INT PRIMARY KEY AUTO_INCREMENT,
KlientID INT NOT NULL,
DataZamowienia DATETIME DEFAULT CURRENT_TIMESTAMP,
CalkowitaKwota DECIMAL(10, 2) NOT NULL,
CONSTRAINT FK_Zamowienia_Klient
FOREIGN KEY (KlientID) REFERENCES Uzytkownicy(ID)
);
-- 5. Dane testowe (DML)
INSERT INTO Uzytkownicy (Imie, Nazwisko, Email) VALUES
('Jan', 'Kowalski', 'jan@example.com'),
('Anna', 'Nowak', 'anna@example.com');
INSERT INTO Ksiazki (Tytul, Autor, Cena, Dostepna, DataWydania) VALUES
('Wladca Pierscieni', 'J.R.R. Tolkien', 65.50, TRUE, '1954-07-29'),
('Hobbit', 'J.R.R. Tolkien', 45.00, TRUE, '1937-09-21'),
('Diuna', 'Frank Herbert', 80.99, TRUE, '1965-08-01');
INSERT INTO Zamowienia (KlientID, CalkowitaKwota) VALUES
(1, 65.50), (1, 45.00), (2, 80.99);
ksiegarnia, w zakładce SQL.
Polecenie: Wyszukaj wszystkie kolumny i rekordy z tabeli Uzytkownicy.
SELECT * FROM Uzytkownicy;
SELECT * wybiera wszystkie kolumny z tabeli wskazanej po FROM. To podstawowe zapytanie DQL (Data Query Language).
Polecenie: Wyszukaj tytuły i ceny wszystkich książek, które kosztują więcej niż 50 zł.
SELECT Tytul, Cena
FROM Ksiazki
WHERE Cena > 50.00;
WHERE filtruje rekordy na podstawie warunku logicznego. Warto podawać konkretne kolumny zamiast *, aby ograniczyć ilość danych.
Polecenie: Dodaj nowego użytkownika i zaktualizuj email użytkownika „Jan Kowalski”.
-- Wstawianie nowego rekordu
INSERT INTO Uzytkownicy (Imie, Nazwisko, Email)
VALUES ('Marta', 'Zielinska', 'marta.zielinska@corp.com');
-- Aktualizacja istniejącego rekordu
UPDATE Uzytkownicy
SET Email = 'jan.kowalski.new@example.com'
WHERE Imie = 'Jan' AND Nazwisko = 'Kowalski';
INSERT dodaje nowe wiersze. UPDATE modyfikuje istniejące – koniecznie z WHERE, aby nie zmienić wszystkich rekordów.
Polecenie: Usuń jedno zamówienie, wyczyść tabelę książek, a następnie usuń tabelę zamówień.
-- 1. Usuwanie konkretnego rekordu
DELETE FROM Zamowienia
WHERE ID = 3;
-- 2. Czyszczenie całej tabeli (reset AUTO_INCREMENT)
TRUNCATE TABLE Ksiazki;
-- 3. Usunięcie całej tabeli
DROP TABLE Zamowienia;
DELETE usuwa wskazane wiersze. TRUNCATE szybko usuwa wszystkie wiersze i resetuje licznik AUTO_INCREMENT. DROP TABLE kasuje strukturę tabeli i jej dane.
Polecenie: Policz liczbę zamówień i sumę wydatków dla każdego klienta.
SELECT KlientID,
COUNT(*) AS LiczbaZamowien,
SUM(CalkowitaKwota) AS SumaWydana
FROM Zamowienia
GROUP BY KlientID;
GROUP BY tworzy grupy według KlientID, a funkcje agregujące (COUNT, SUM) obliczają wyniki dla każdej grupy.
Polecenie: Połącz dane klientów z ich zamówieniami – tylko tych, którzy coś zamówili.
SELECT U.Imie, U.Nazwisko, Z.DataZamowienia, Z.CalkowitaKwota
FROM Uzytkownicy U
INNER JOIN Zamowienia Z ON U.ID = Z.KlientID;
INNER JOIN zwraca tylko wiersze, dla których istnieje dopasowanie po obu stronach złączenia (tu: U.ID = Z.KlientID).
Polecenie: Znajdź klientów, których nazwisko zaczyna się na „K” lub „N”.
SELECT Imie, Nazwisko, Email
FROM Uzytkownicy
WHERE Nazwisko LIKE 'K%' OR Nazwisko LIKE 'N%';
LIKE służy do dopasowywania wzorców. Znak % oznacza dowolną sekwencję znaków (także pustą).
Polecenie: Wyświetl unikalną listę nazwisk użytkowników i tytułów książek w jednej kolumnie.
SELECT Nazwisko AS Nazwa, 'Uzytkownik' AS Typ
FROM Uzytkownicy
UNION
SELECT Tytul AS Nazwa, 'Ksiazka' AS Typ
FROM Ksiazki;
UNION łączy wyniki wielu zapytań SELECT. Wymaga zgodnej liczby kolumn i kompatybilnych typów danych.
Polecenie: Znajdź książki droższe niż średnia cena wszystkich książek.
SELECT Tytul, Cena
FROM Ksiazki
WHERE Cena > (
SELECT AVG(Cena) FROM Ksiazki
);
WHERE w zapytaniu zewnętrznym.
Polecenie: Pokaż klientów, którzy złożyli więcej niż jedno zamówienie.
SELECT KlientID,
COUNT(ID) AS LiczbaZamowien
FROM Zamowienia
GROUP BY KlientID
HAVING COUNT(ID) > 1;
HAVING filtruje wyniki po zastosowaniu GROUP BY i funkcji agregujących. WHERE COUNT(ID) byłoby niepoprawne składniowo.
Polecenie: Zadbaj, by cena książki była zawsze dodatnia.
ALTER TABLE Ksiazki
ADD CONSTRAINT CHK_CenaDodatnia
CHECK (Cena > 0);
CHECK jest egzekwowane przez silnik InnoDB i blokuje wstawienie/aktualizację rekordów niespełniających warunku.
Polecenie: Utwórz widok RaportKlientow pokazujący tylko użytkowników z adresem w domenie @example.com.
CREATE VIEW RaportKlientow AS
SELECT Imie, Nazwisko, Email
FROM Uzytkownicy
WHERE Email LIKE '%@example.com';
-- Użycie widoku:
-- SELECT * FROM RaportKlientow;
Polecenie: Policz, ile książek wydano w każdym roku.
SELECT
YEAR(DataWydania) AS RokWydania,
COUNT(ID) AS LiczbaKsiazek
FROM Ksiazki
GROUP BY RokWydania
HAVING RokWydania IS NOT NULL;
YEAR() wyciąga rok z daty. Grupowanie po aliasie RokWydania poprawia czytelność zapytania.
Polecenie: Utwórz indeks na kolumnie Nazwisko w tabeli Uzytkownicy.
CREATE INDEX idx_nazwisko
ON Uzytkownicy (Nazwisko);
-- Usunięcie indeksu (opcjonalnie):
-- DROP INDEX idx_nazwisko ON Uzytkownicy;