Zadanie 110: Relacje N:M (Wiele do Wielu)

MySQL
Priorytet: Normalny Szkic

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"