Mam 2 takie tabele:
> SELECT * FROM table_a;
+------+------+
| id | name |
+------+------+
| 1 | row1 |
| 2 | row2 |
+------+------+
> SELECT * FROM table_b;
+------+------+------+
| id | name | aid |
+------+------+------+
| 3 | row3 | 1 |
| 4 | row4 | 1 |
| 5 | row5 | NULL |
+------+------+------+
INNER JOIN dba o oba stoły
INNER JOIN dba o obie tabele, więc otrzymujesz wiersz tylko wtedy, gdy obie tabele mają jeden. Jeśli jest więcej niż jedna pasująca para, otrzymasz wiele wierszy.
> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id | name | id | name | aid |
+------+------+------+------+------+
| 1 | row1 | 3 | row3 | 1 |
| 1 | row1 | 4 | row4 | 1 |
+------+------+------+------+------+
Nie ma znaczenia dla INNER JOIN, jeśli odwrócisz kolejność, ponieważ zależy to na obu tabelach:
> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id | name | aid | id | name |
+------+------+------+------+------+
| 3 | row3 | 1 | 1 | row1 |
| 4 | row4 | 1 | 1 | row1 |
+------+------+------+------+------+
Otrzymujesz te same wiersze, ale kolumny są w innej kolejności, ponieważ wspomnieliśmy o tabelach w innej kolejności.
LEFT JOIN dba tylko o pierwszy stół
LEFT JOIN dba o pierwszą tabelę, którą mu podasz, i nie przejmuje się zbytnio drugą, więc zawsze otrzymujesz wiersze z pierwszej tabeli, nawet jeśli nie ma odpowiadającego wiersza w drugiej:
> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id | name | id | name | aid |
+------+------+------+------+------+
| 1 | row1 | 3 | row3 | 1 |
| 1 | row1 | 4 | row4 | 1 |
| 2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+
Powyżej możesz zobaczyć wszystkie wiersze tabeli table_a, mimo że niektóre z nich nie pasują do niczego w tabeli b, ale nie wszystkie wiersze tabeli table_b - tylko te, które pasują do czegoś w tabeli table_a.
Jeśli odwrócimy kolejność tabel, LEFT JOIN zachowuje się inaczej:
> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id | name | aid | id | name |
+------+------+------+------+------+
| 3 | row3 | 1 | 1 | row1 |
| 4 | row4 | 1 | 1 | row1 |
| 5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+
Teraz otrzymujemy wszystkie wiersze tabeli table_b, ale tylko pasujące wiersze tabeli table_a.
RIGHT JOIN dba tylko o drugi stół
a RIGHT JOIN b
dostajesz dokładnie te same wiersze, co b LEFT JOIN a
. Jedyną różnicą jest domyślna kolejność kolumn.
> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id | name | id | name | aid |
+------+------+------+------+------+
| 1 | row1 | 3 | row3 | 1 |
| 1 | row1 | 4 | row4 | 1 |
| NULL | NULL | 5 | row5 | NULL |
+------+------+------+------+------+
To są te same rzędy table_b LEFT JOIN table_a
, które widzieliśmy w sekcji LEFT JOIN.
Podobnie:
> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id | name | aid | id | name |
+------+------+------+------+------+
| 3 | row3 | 1 | 1 | row1 |
| 4 | row4 | 1 | 1 | row1 |
| NULL | NULL | NULL | 2 | row2 |
+------+------+------+------+------+
To te same rzędy, co table_a LEFT JOIN table_b
.
Żadne połączenie w ogóle nie daje kopii wszystkiego
Bez klauzuli Join: Jeśli piszesz tabele bez klauzuli JOIN, oddzielone przecinkami, otrzymasz każdy wiersz pierwszej tabeli zapisany obok każdego wiersza drugiej tabeli, w każdej możliwej kombinacji:
> SELECT * FROM table_b, table_a;
+------+------+------+------+------+
| id | name | aid | id | name |
+------+------+------+------+------+
| 3 | row3 | 1 | 1 | row1 |
| 3 | row3 | 1 | 2 | row2 |
| 4 | row4 | 1 | 1 | row1 |
| 4 | row4 | 1 | 2 | row2 |
| 5 | row5 | NULL | 1 | row1 |
| 5 | row5 | NULL | 2 | row2 |
+------+------+------+------+------+
(To jest z mojego wpisu na blogu Przykłady typów sprzężeń SQL )