Zadanie 110: Relacje N:M (Wiele do Wielu)
Zadanie 110: Relacje Wiele do Wielu (N:M) w MySQL - Studenci i Kursy
Wstęp
Relacja Wiele do Wielu (N:M) występuje, gdy jeden rekord z tabeli A może być powiązany z wieloma rekordami z tabeli B, i odwrotnie. Przykład: Jeden Student może zapisać się na wiele Kursów, a jeden Kurs może mieć wielu Studentów.
W relacyjnych bazach danych nie da się stworzyć bezpośredniej relacji N:M między dwiema tabelami. Potrzebujemy trzeciej tabeli łącznikowej (Junction Table), np. Zapisy.
Diagram:
Studenci (1) <--- (N) Zapisy (M) ---> (1) Kursy
Część 1: Struktura Bazy (DDL)
Zadanie 1: Utworzenie bazy i tabel
Stwórz bazę Szkola i trzy tabele.
CREATE DATABASE Szkola;
USE Szkola;
-- Tabela Studenci
CREATE TABLE Studenci (
id INT AUTO_INCREMENT PRIMARY KEY,
imie VARCHAR(50),
nazwisko VARCHAR(50),
indeks INT UNIQUE
);
-- Tabela Kursy
CREATE TABLE Kursy (
id INT AUTO_INCREMENT PRIMARY KEY,
nazwa VARCHAR(100),
opis TEXT
);
-- Tabela Łącznikowa: Zapisy
CREATE TABLE Zapisy (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id INT,
kurs_id INT,
FOREIGN KEY (student_id) REFERENCES Studenci(id),
FOREIGN KEY (kurs_id) REFERENCES Kursy(id)
);
Tabela Zapisy przechowuje pary: Kto (student_id) zapisał się na Co (kurs_id).
Część 2: Dane (DML)
Zadanie 2: Wstawianie danych
-- Dodaj studentów
INSERT INTO Studenci (imie, nazwisko, indeks) VALUES
('Anna', 'Nowak', 1001),
('Jan', 'Kowalski', 1002),
('Piotr', 'Wiśniewski', 1003),
('Maria', 'Zielińska', 1004);
-- Dodaj kursy
INSERT INTO Kursy (nazwa, opis) VALUES
('Wstęp do SQL', 'Podstawy baz danych'),
('Programowanie w Java', 'Od zera do bohatera'),
('Administracja Linux', 'Zarządzanie serwerem'),
('Grafika Komputerowa', 'Photoshop i Blender');
-- Zapisz studentów na kursy (Wypełniamy tabelę Zapisy)
-- Anna (1) na SQL (1) i Java (2)
INSERT INTO Zapisy (student_id, kurs_id) VALUES (1, 1);
INSERT INTO Zapisy (student_id, kurs_id) VALUES (1, 2);
-- Jan (2) na Linux (3)
INSERT INTO Zapisy (student_id, kurs_id) VALUES (2, 3);
-- Piotr (3) na WSZYSTKO (1, 2, 3, 4)
INSERT INTO Zapisy (student_id, kurs_id) VALUES (3, 1), (3, 2), (3, 3), (3, 4);
-- Maria (4) na... nic (nie dodajemy wpisu)
Część 3: Przykłady SELECT (JOIN)
Przykład 1: Kto na co chodzi? (INNER JOIN)
Wyświetla tylko studentów, którzy mają jakieś kursy.
SELECT s.imie, s.nazwisko, k.nazwa
FROM Studenci s
JOIN Zapisy z ON s.id = z.student_id
JOIN Kursy k ON z.kurs_id = k.id;
Przykład 2: Wszyscy studenci i ich kursy (LEFT JOIN)
Wyświetla wszystkich studentów. Jeśli nie ma kursu -> NULL.
SELECT s.imie, s.nazwisko, k.nazwa
FROM Studenci s
LEFT JOIN Zapisy z ON s.id = z.student_id
LEFT JOIN Kursy k ON z.kurs_id = k.id;
Zauważ, że Maria Zielińska będzie miała NULL w kolumnie nazwa.
Część 4: Zadania do wykonania (SELECT)
Wykonaj poniższe polecenia SQL.
Zadanie 3: Lista obecności na Javie
Wybierz imiona i nazwiska studentów zapisanych na kurs "Programowanie w Java". (Wskazówka: JOIN trzech tabel + WHERE nazwa kursu)
Zadanie 4: Liczebność grup
Policz, ilu studentów jest zapisanych na każdy kurs. Wyświetl nazwę kursu i liczbę studentów. (Wskazówka: GROUP BY k.nazwa)
Zadanie 5: Studenci bez aktywności
Znajdź studentów, którzy nie są zapisani na żaden kurs. (Wskazówka: LEFT JOIN ... WHERE k.id IS NULL)
Zadanie 6: Najpopularniejszy kurs
Wyświetl nazwę kursu, który ma najwięcej zapisanych studentów (posortuj malejąco).
Zadanie 7: Szukaj Piotra
Znajdź wszystkie kursy, na które zapisał się student o imieniu 'Piotr'.
Commit
git add .
git commit -m "MySQL Zadanie 110: Relacja N:M Studenci-Kursy"