Lekcja dla chętnych, poznajemy joiny SQLowe, ich terminologię, bo wcześniej już się nimi bawiliśmy, ale bez większego zastanowienia. Do dzieła.

Natural Join nie potrzebuje kluczy obcych ani warunków. Potrzebuje natomiast dwóch tabel, w których nazwa kolumny się pokrywa:

Create Table department
(
   DEPT_NAME Varchar(20),
   MANAGER_NAME Varchar(255)
);

Create Table employee
(
   EMP_ID int,
   EMP_NAME Varchar(20),
   DEPT_NAME Varchar(255)
);

Natural join nie pozwala na aliasowanie tabel, nie wymaga warunków ani kluczy obcych, nie jest dobrą praktyką, wykonujemy go tak:

SELECT *
FROM employee
NATURAL JOIN department;

Jedną z nielicznych zalet natural joina jest to, że w result secie nie znajdą się dwie kolumny o identycznej nazwie. Inna to walor dydaktyczny, na początku nauki SQLa dla uproszczenia można to podać jako przykład samej idei czym jest join bez przytłaczania składnią SQL.

Inner Join – łączymy dwie tabele ze sobą. Jeżeli coś pasuje według warunku (po prawej i po lewej nie ma nulla) to zostaje wrzucone w result set (dlatego inner, te części okręgu, które się pokrywają).

Jeżeli po prawej albo po lewej coś nie jest spasowane, to jest wywalone. Robiliśmy już inner join:

select `ppl`.*, `addr`.`city`, `addr`.`street` 
from `people` as `ppl` 
inner join 
`addresses` as `addr` 
on `ppl`.`id` = `addr`.`person_id`

Czyli bierzemy kółko z ppl i kółko z addr. Te, które się pokrywają (inner part) to te, w których zachodzi odniesienie, adres istnieje i wskazuje na osobę.

Osoby bez adresu i adresy bez osób wywalone z result setu.

Left outer join – to taki join, który bierze to, co po lewej i część wspólną. Przykład nam znany:

select `ppl`.*, `addr`.`city`, `addr`.`street` 
from `people` as `ppl` 
left join 
`addresses` as `addr` 
on `ppl`.`id` = `addr`.`person_id`; 

To weźmie wszystkie osoby (te z adresem i bez) i wyświetli po lewej. Po prawej doklei te adresy, które pasują do osób, a tam gdzie po prawej nie ma czegoś to będzie po prostu null.

Right outer join – taka sama logika, tylko cała prawa jest w result secie + pasujące kolumny z lewej.

Self join – potrzebujemy tabeli, której klucz obcy jest odniesieniem do jej własnego, nie cudzego, klucza głównego:

CREATE TABLE employees (
    employee_id INT PRIMARY KEY,
    employee_name VARCHAR(50),
    manager_id INT,
    FOREIGN KEY (manager_id) REFERENCES employees(employee_id)
);

Teraz możemy zrobić self join:

SELECT e1.employee_id AS employee_id, 
       e1.employee_name AS employee_name, 
       e2.employee_name AS manager_name
FROM employees e1
INNER JOIN employees e2 ON e1.manager_id = e2.employee_id;

Nieważne, czy join jest inner, left, right, jest self joinem ponieważ robimy joina na tabeli względem samej siebie. Tutaj pokazuje id pracownika, imię pracownika i imię managera, mimo że taka kolumna nie istnieje – jest tylko manager_id pokazujący inny rekord z tej samej tabeli.

Tu taki sam przykład, tylko że mamy left joina, zatem osoby bez managera też będą, tylko null w manager_name:

SELECT e1.employee_id AS employee_id, 
       e1.employee_name AS employee_name, 
       e2.employee_name AS manager_name
FROM employees e1
LEFT JOIN employees e2 ON e1.manager_id = e2.employee_id;

Mamy jeszcze cross-join, czyli kartezjański, czyli każdy z każdym. Nie robi się takich joinów zazwyczaj. Ok, przykład:

SELECT m.director, 
r.author 
FROM `reviews` as r 
CROSS JOIN `movies` as m; 

Czyli umówiliśmy każdego reżysera z każdym autorem na spotkanie. I wszystkie możliwe pary reżyser-autor są w result-secie.

Większość tych rzeczy nie powinna już robić na nas wrażena.