SELF JOIN — to sposób na połączenie tabeli z samą sobą. Może to brzmieć dziwnie na pierwszy rzut oka: po co łączyć tabelę z samą sobą? Ale w realnym świecie takie zadania pojawiają się całkiem często. Na przykład wyobraź sobie, że masz tabelę pracowników i każdy pracownik ma menedżera. Menedżer też jest pracownikiem, więc jego dane są w tej samej tabeli. SELF JOIN pomoże nam powiązać pracowników z ich menedżerami.
Formalnie rzecz biorąc, SELF JOIN to zwykły JOIN, ale używamy tej samej tabeli dwa razy, nadając jej różne aliasy, żeby odróżnić jej "wersje".
SELF JOIN można użyć do:
- Relacji hierarchicznych: ustalania relacji "rodzic-dziecko", np. pracownik i jego menedżer.
- Analizy danych w obrębie jednej tabeli: porównywania rekordów w tabeli, np. szukania podobnych produktów lub zdarzeń.
- Zaawansowanych zapytań do struktur z powtarzającą się logiką.
Składnia SELF JOIN
Dla jasności od razu zobaczmy uproszczoną składnię SELF JOIN:
SELECT
A.column_name,
B.column_name
FROM
table_name A
JOIN
table_name B
ON
A.common_column = B.common_column;
Tutaj:
table_name Aitable_name B— to ta sama tabela, ale z różnymi aliasami.A.common_columniB.common_column— kolumny, które są używane do łączenia rekordów.
Aliasów (A i B) potrzebujemy, żeby DBMS "wiedział", z którą "kopią" tabeli pracujesz.
Przykłady użycia SELF JOIN
Przykład 1: lista pracowników i ich menedżerów
Załóżmy, że mamy tabelę employees, która wygląda tak:
| employee_id | name | manager_id |
|---|---|---|
| 1 | Alex Lin | NULL |
| 2 | Maria Chi | 1 |
| 3 | Otto Song | 1 |
| 4 | Nina Zhao | 2 |
W tej tabeli:
employee_id— identyfikator pracownika.name— imię pracownika.manager_id— identyfikator menedżera, który też jestemployee_idinnego pracownika.
Zadanie: uzyskać listę pracowników i ich menedżerów.
Tak to się robi z użyciem SELF JOIN:
SELECT
e.name AS employee_name,
m.name AS manager_name
FROM
employees e
LEFT JOIN
employees m
ON
e.manager_id = m.employee_id;
Wynik:
| employee_name | manager_name |
|---|---|
| Alex Lin | NULL |
| Maria Chi | Alex Lin |
| Otto Song | Alex Lin |
| Nina Zhao | Maria Chi |
Tutaj:
- Tabela
e— to "pracownicy". - Tabela
m— to też "pracownicy", ale w roli "menedżerów".
Alex Lin nie ma menedżera manager_id = NULL, więc w wyniku pole manager_name będzie puste.
Przykład 2: Szukanie podobnych produktów
Załóżmy, że mamy tabelę products:
| product_id | product_name | category |
|---|---|---|
| 1 | Lodówka | Technika |
| 2 | Pralka | Technika |
| 3 | Smartfon | Gadżety |
| 4 | Tablet | Gadżety |
Zadanie: znaleźć pary produktów, które należą do tej samej kategorii.
Rozwiązanie z użyciem SELF JOIN:
SELECT
p1.product_name AS product_1,
p2.product_name AS product_2
FROM
products p1
JOIN
products p2
ON
p1.category = p2.category
AND
p1.product_id < p2.product_id;
Wynik:
| product_1 | product_2 |
|---|---|
| Lodówka | Pralka |
| Smartfon | Tablet |
Zwróć uwagę na warunek p1.product_id < p2.product_id. Dzięki temu unikamy duplikatów par, np. żeby nie pojawiały się w wynikach zarówno Lodówka — Pralka, jak i Pralka — Lodówka.
Przykład 3: Analiza hierarchii (rodzice i potomkowie)
Zobaczmy jeszcze jeden przykład. Załóżmy, że mamy tabelę categories:
| category_id | category_name | parent_id |
|---|---|---|
| 1 | Technika | NULL |
| 2 | Gadżety | 1 |
| 3 | Komputery | 1 |
| 4 | Smartfony | 2 |
Tutaj:
category_id— identyfikator kategorii.category_name— nazwa kategorii.parent_id— identyfikator kategorii nadrzędnej.
Zadanie: powiązać kategorie z ich kategoriami nadrzędnymi.
Zapytanie:
SELECT
c1.category_name AS child_category,
c2.category_name AS parent_category
FROM
categories c1
LEFT JOIN
categories c2
ON
c1.parent_id = c2.category_id;
Wynik:
| child_category | parent_category |
|---|---|
| Technika | NULL |
| Gadżety | Technika |
| Komputery | Technika |
| Smartfony | Gadżety |
Typowe błędy przy użyciu SELF JOIN
Zapomniane aliasy: jeśli nie użyjesz aliasów, nie da się odróżnić jednej "kopii" tabeli od drugiej.
Cykliczne odwołania: jeśli dane zawierają cykliczne odwołania (np. pracownik jest swoim własnym menedżerem), może to prowadzić do nieoczekiwanych wyników.
Duplikaty wyników: nie zapomnij filtrować wyników (np. przez p1.product_id < p2.product_id), żeby uniknąć duplikatów.
SELF JOIN — to potężne narzędzie do pracy z danymi, a jego poprawne użycie pozwala rozwiązywać trudne zadania z hierarchiami, relacjami w obrębie tabel i analizą danych. Mam nadzieję, że teraz widzisz, jak przydatny jest ten "selfik" w świecie SQL!
GO TO FULL VERSION