Dzisiaj ogarniemy najbardziej demokratyczną formę łączenia danych — FULL OUTER JOIN. To taki join, gdzie każdy chętny trafia do wyniku, nawet jeśli nie ma dla niego pary.
FULL OUTER JOIN — to rodzaj łączenia danych, gdzie zwracane są wszystkie wiersze z obu tabel. Jeśli dla wiersza z jednej tabeli nie ma odpowiadającego wiersza w drugiej, brakujące wartości w wyniku będą NULL. To jakby robić listę wszystkich osób, które przyszły na dwie różne imprezy: nawet jeśli ktoś był tylko na jednej, i tak będzie uwzględniony.
Wizualnie wygląda to tak:
Tabela A Tabela B
+----+----------+ +----+----------+
| id | name | | id | course |
+----+----------+ +----+----------+
| 1 | Alice | | 2 | Math |
| 2 | Bob | | 3 | Physics |
| 4 | Charlie | | 5 | History |
+----+----------+ +----+----------+
FULL OUTER JOIN WYNIK:
+----+----------+----------+
| id | name | course |
+----+----------+----------+
| 1 | Alice | NULL |
| 2 | Bob | Math |
| 3 | NULL | Physics |
| 4 | Charlie | NULL |
| 5 | NULL | History |
+----+----------+----------+
Wiersze bez dopasowania zostają, ale dane dla brakujących kolumn będą miały NULL.
Składnia FULL OUTER JOIN
Składnia jest prosta, ale daje sporo mocy:
SELECT
kolumny
FROM
tabela1
FULL OUTER JOIN
tabela2
ON tabela1.wspolna_kolumna = tabela2.wspolna_kolumna;
Kluczowa część to FULL OUTER JOIN, która każe PostgreSQL zwrócić wszystkie wiersze z obu tabel. Jeśli dla jakiegoś wiersza nie ma pary według warunku ON, wartości są zamieniane na NULL.
Przykłady użycia
Przejdźmy przez konkretne przykłady na bazie dobrze znanej bazy university z tabelami students i enrollments.
Przykład 1: lista wszystkich studentów i kursów
Wyobraź sobie, że mamy dwie tabele:
Tabela students:
| student_id | name |
|---|---|
| 1 | Alice |
| 2 | Bob |
| 3 | Charlie |
Tabela enrollments:
| enrollment_id | student_id | course |
|---|---|---|
| 101 | 1 | Math |
| 102 | 2 | Physics |
| 103 | 4 | History |
Naszym zadaniem jest zrobić pełną listę studentów i kursów, w tym tych studentów, którzy nie są zapisani na żaden kurs, i kursów bez studentów.
Oto zapytanie:
SELECT
s.student_id,
s.name,
e.course
FROM
students s
FULL OUTER JOIN
enrollments e
ON
s.student_id = e.student_id;
Wynik:
| student_id | name | course |
|---|---|---|
| 1 | Alice | Math |
| 2 | Bob | Physics |
| 3 | Charlie | NULL |
| NULL | NULL | History |
Jak widzisz, w wyniku są wszyscy studenci i wszystkie kursy. Student Charlie nie jest zapisany na żaden kurs, więc dla niego pole course to NULL. A kurs History nie ma studenta, więc jego student_id i name to NULL.
Przykład 2: Analiza sprzedaży i produktów
Teraz pomyślmy o sklepie. Mamy dwie tabele:
Tabela products:
| product_id | name |
|---|---|
| 1 | Laptop |
| 2 | Smartphone |
| 3 | Printer |
Tabela sales:
| sale_id | product_id | quantity |
|---|---|---|
| 101 | 1 | 5 |
| 102 | 3 | 2 |
| 103 | 4 | 10 |
Chcemy dostać pełną listę wszystkich produktów i sprzedaży, w tym tych produktów, które nie zostały sprzedane, i sprzedaży z nieprawidłowymi product_id.
Zapytanie:
SELECT
p.product_id,
p.name AS product_name,
s.quantity
FROM
products p
FULL OUTER JOIN
sales s
ON
p.product_id = s.product_id;
Wynik:
| product_id | product_name | quantity |
|---|---|---|
| 1 | Laptop | 5 |
| 2 | Smartphone | NULL |
| 3 | Printer | 2 |
| NULL | NULL | 10 |
Widzimy, że Smartphone nie miał sprzedaży (quantity = NULL), a sprzedaż z product_id = 4 nie pasuje do żadnego produktu.
Zadanie praktyczne
Spróbuj napisać zapytanie dla tabel departments i employees:
Tabela departments:
| department_id | department_name |
|---|---|
| 1 | HR |
| 2 | IT |
| 3 | Marketing |
Tabela employees:
| employee_id | department_id | name |
|---|---|---|
| 101 | 1 | Alice |
| 102 | 2 | Bob |
| 103 | 4 | Charlie |
Napisz FULL OUTER JOIN, żeby dostać pełną listę departamentów i pracowników. Brakujące dane uzupełnij NULL.
Jak ogarniać wartości NULL
Problem NULL to nieunikniona konsekwencja używania FULL OUTER JOIN. W realnych zadaniach możesz chcieć zamienić NULL na bardziej czytelne wartości. W PostgreSQL możesz to zrobić przez funkcję COALESCE().
Przykład:
SELECT
COALESCE(s.name, 'Brak Studenta') AS student_name,
COALESCE(e.course, 'Brak Kursu') AS course_name
FROM
students s
FULL OUTER JOIN
enrollments e
ON
s.student_id = e.student_id;
Wynik:
| student_name | course_name |
|---|---|
| Alice | Math |
| Bob | Physics |
| Charlie | Brak Kursu |
| Brak Studenta | History |
Teraz zamiast NULL mamy czytelne wartości, które robią raporty bardziej zrozumiałymi.
Kiedy używać FULL OUTER JOIN
FULL OUTER JOIN przydaje się, gdy musisz widzieć wszystkie dane z obu tabel, nawet jeśli nie są w pełni powiązane. Przykłady:
- Raporty sprzedaży i produktów — żeby zobaczyć zarówno sprzedane, jak i niesprzedane produkty.
- Analiza studentów i kursów — żeby sprawdzić, czy nie ma nieujętych danych.
- Porównanie list — np. żeby wykryć różnice między dwoma zbiorami danych.
Mam nadzieję, że ten wykład dał Ci dobre pojęcie o FULL OUTER JOIN. Teraz przed Tobą ciekawy świat bardziej zaawansowanych joinów i ogarniania danych!
GO TO FULL VERSION