Lekcja 3: Joins i Relacje — Zróbmy, Żeby Twoje Tabele Gadały ze Sobą!


Lesson3

Lekcja 3: Joins i Relacje — Zróbmy, Żeby Twoje Tabele Gadały ze Sobą!

Witaj ponownie, dzielny rycerzu danych! Teraz, kiedy już wiesz, jak tworzyć i zarządzać swoimi tabelami, czas dodać im trochę… hmmm, socjalnych umiejętności. W końcu tabele nie powinny siedzieć zamknięte w swoich zamkach, unikając spojrzeń i przemykając na paluszkach. Nie, nie, one muszą rozmawiać! Dziś zagłębimy się w świat Joins i Relacji — coś w stylu tanecznego party, gdzie każda tabela wybiera swojego partnera!

Co to jest Join?

Mówiąc najprościej, Join to sposób powiedzenia PostgreSQL: „Hej, posadź te dwie tabele razem i spraw, żeby pogadały!”. Joins pozwalają łączyć dane z dwóch lub więcej tabel na podstawie wspólnej kolumny. Wyobraź sobie, że organizujesz przyjęcie, na którym każdy stół ma wyjątkową listę gości, ale wszyscy mają coś wspólnego (na przykład miłość do pierogów z kapustą).

Rodzaje Joins: Kto z Kim Się Dogada?

Istnieje kilka typów joins, każdy z własnym charakterem. Przyjrzyjmy się temu, kto jest kim na tym przyjęciu:

  1. INNER JOIN: „Spotkajmy się, jeśli mamy coś wspólnego.”
  2. LEFT JOIN: „Wszyscy z lewej tabeli są zaproszeni, a z prawej — tylko wybrani.”
  3. RIGHT JOIN: Przeciwieństwo LEFT JOIN — główną rolę gra prawa tabela, a lewa może dołączyć, jeśli ma szczęście.
  4. FULL OUTER JOIN: „Wszyscy są mile widziani!” (Nawet ci, którzy wpadli przez przypadek.)

Sprawdźmy, jak to działa w praktyce!

1. INNER JOIN: Dla Wybranych

INNER JOIN zwraca tylko te wiersze, które mają pasujące wartości w obu tabelach. Wyobraź sobie, że masz tabelę rycerze i tabelę misje. Tabela rycerze zawiera wszystkich rycerzy, a misje to lista misji, na które się zapisali:

CREATE TABLE rycerze (
    id SERIAL PRIMARY KEY,
    imie VARCHAR(100),
    krolestwo VARCHAR(50)
);

CREATE TABLE misje (
    id SERIAL PRIMARY KEY,
    rycerz_id INT,
    nazwa_misji VARCHAR(100)
);

Teraz sprawdźmy, którzy rycerze podjęli się misji:

SELECT rycerze.imie, misje.nazwa_misji
FROM rycerze
INNER JOIN misje
ON rycerze.id = misje.rycerz_id;

To zwróci listę rycerzy, którzy obecnie są na misji. Jeśli rycerz siedzi w Camelocie i gra w szachy z Merlinem — tutaj go nie znajdziesz. (Przepraszam, Sir Lancelot, znajdź sobie jakieś zajęcie!)

2. LEFT JOIN: Gościnny Gospodarz

LEFT JOIN zwraca wszystkie wiersze z lewej tabeli (rycerze), a także pasujące wiersze z prawej tabeli (misje). Jeśli nie ma dopasowań, wynik to NULL dla kolumn z prawej tabeli. To jak zaprosić wszystkich rycerzy na bal i sprawdzić, kto naprawdę ma coś do roboty.

SELECT rycerze.imie, misje.nazwa_misji
FROM rycerze
LEFT JOIN misje
ON rycerze.id = misje.rycerz_id;

Nawet jeśli rycerz po prostu siedzi i poleruje swoją zbroję, pojawi się na liście — ale z NULL jako misją. Cóż, nie każdy rycerz ma szczęście…

3. RIGHT JOIN: Spójrzmy z Drugiej Strony

RIGHT JOIN działa na odwrót — zwraca wszystkie wiersze z prawej tabeli (misje) i pasujące wiersze z lewej tabeli (rycerze). To jak zapytać: „Jakie misje są dostępne i kto jest na tyle odważny, żeby je podjąć?”

SELECT rycerze.imie, misje.nazwa_misji
FROM rycerze
RIGHT JOIN misje
ON rycerze.id = misje.rycerz_id;

To pokaże wszystkie misje, nawet jeśli niektóre z nich po prostu czekają, aż jakiś odważny rycerz się zjawi.

4. FULL OUTER JOIN: Wielka Impreza!

FULL OUTER JOIN zwraca wszystkie wiersze, kiedy jest dopasowanie w lewej lub prawej tabeli. Jeśli nie ma dopasowań, otrzymasz NULL. To jak zaprosić wszystkich na imprezę, nawet jeśli nie mają pojęcia, kto organizuje.

SELECT rycerze.imie, misje.nazwa_misji
FROM rycerze
FULL OUTER JOIN misje
ON rycerze.id = misje.rycerz_id;

Ten zapytanie pokaże wszystkich rycerzy i wszystkie misje, bez względu na to, czy mają ze sobą coś wspólnego. Wyobraź sobie to jako wielki targ, gdzie wszyscy sprzedają, ale nikt nie kupuje.

Tworzenie Relacji: Klucze Główne i Obce

Jak powiedzieć PostgreSQL, że rycerz_id w tabeli misje jest powiązany z kolumną id w tabeli rycerze? Oto zaczyna się prawdziwa magia relacji.

  1. Klucz Główny (Primary Key): To jak dowód osobisty rycerza. Unikalnie identyfikuje każdy wiersz w tabeli. W naszym przypadku rycerze.id to klucz główny.
  2. Klucz Obcy (Foreign Key): To jak zaproszenie na turniej. Odnosi się do klucza głównego w innej tabeli. Tutaj misje.rycerz_id to klucz obcy, który wskazuje na rycerze.id.

Oficjalne Dodanie Klucza Obcego

Zróbmy to oficjalnie, dodając ograniczenie klucza obcego do naszej tabeli misje:

ALTER TABLE misje
ADD CONSTRAINT fk_rycerz
FOREIGN KEY (rycerz_id)
REFERENCES rycerze(id);

Teraz PostgreSQL wie, że misje.rycerz_id musi pasować do rycerze.id. Jeśli spróbujesz dodać misję dla nieistniejącego rycerza, PostgreSQL zatrzyma cię szybciej niż smok!

Podsumowanie: Co Dzisiaj Przerobiliśmy?

Dzisiaj poznaliśmy:

  • INNER JOIN: Zwraca wiersze z obu tabel, jeśli jest dopasowanie.
  • LEFT JOIN: Zwraca wszystkie wiersze z lewej tabeli, nawet jeśli prawa jest pusta.
  • RIGHT JOIN: Zwraca wszystkie wiersze z prawej tabeli.
  • FULL OUTER JOIN: Wszyscy są zaproszeni, nawet jeśli nie wiedzą, po co przyszli.

Niech twoje Joins będą zawsze szybkie, a wyniki — bezbłędne!