Inne

MySQL: Łączenie tabel – JOIN i UNION

Określenie bazy danych mianem relacyjnej dotyczy tak naprawdę modelu relacji, o który oparta jest baza danych.

Model relacji to model organizacji danych bazujący na matematycznej teorii mnogości, w szczególności na pojęciu relacji. Co to nam daje?

Dzięki pewnym związkom w strukturze przechowywanych w tabelach danych możemy je łączyć otrzymując w pojedynczym wierszu dane z kilku tabel, które są ze sobą powiązane, to co je łączy to właśnie relacja.

Struktura tabel

Omówimy proces łączenia tabel na dwóch bardzo prostych tabelach zawierających po jednej kolumnie z liczbami. Niektóre liczby będą wspólne dla obu tabel, a niektóre będą unikatowe.

--
-- Struktura tabeli dla tabeli `a`
--

CREATE TABLE IF NOT EXISTS `a` (
`an` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Zrzut danych tabeli `a`
--

INSERT INTO `a` (`an`) VALUES
(1),
(2),
(3),
(4),
(5),
(6),
(8),
(10),
(12),
(14);

--
-- Struktura tabeli dla tabeli `b`
--

CREATE TABLE IF NOT EXISTS `b` (
`bn` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Zrzut danych tabeli `b`
--

INSERT INTO `b` (`bn`) VALUES
(1),
(2),
(3),
(4),
(5),
(7),
(9),
(11),
(13),
(15);

JOIN i INNER JOIN

JOIN i INNER JOIN są sobie równoważne i powodują pokazanie tylko rekordów, które zostały dopasowane z obu tabel.

mysql> SELECT *
    -> FROM `a`
    -> JOIN `b` ON `a`.`an` = `b`.`bn`;
+----+----+
| an | bn |
+----+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+----+

mysql> SELECT *
    -> FROM `a`
    -> INNER JOIN `b` ON `a`.`an` = `b`.`bn`;
+----+----+
| an | bn |
+----+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+----+

LEFT JOIN i LEFT OUTER JOIN

LEFT JOIN i LEFT OUTER JOIN są sobie równe, powodują pokazanie wszystkich rekordów z lewej tabeli niezależnie od tego czy dopasowano wartość z tabeli prawej.

mysql> SELECT *
    -> FROM `a`
    -> LEFT JOIN `b` ON `a`.`an` = `b`.`bn`;
+----+------+
| an | bn |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | NULL |
| 8 | NULL |
| 10 | NULL |
| 12 | NULL |
| 14 | NULL |
+----+------+

mysql> SELECT *
    -> FROM `a`
    -> LEFT OUTER JOIN `b` ON `a`.`an` = `b`.`bn`;
+----+------+
| an | bn |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | NULL |
| 8 | NULL |
| 10 | NULL |
| 12 | NULL |
| 14 | NULL |
+----+------+

RIGHT JOIN i RIGHT OUTER JOIN

RIGHT JOIN i RIGHT OUTER JOIN są sobie równe, powodują pokazanie wszystkich rekordów z prawej tabeli niezależnie od tego czy dopasowano wartość z tabeli lewej.

mysql> SELECT *
    -> FROM `a`
    -> RIGHT JOIN `b` ON `a`.`an` = `b`.`bn`;
+------+----+
| an | bn |
+------+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| NULL | 7 |
| NULL | 9 |
| NULL | 11 |
| NULL | 13 |
| NULL | 15 |
+------+----+

mysql> SELECT *
    -> FROM `a`
    -> RIGHT OUTER JOIN `b` ON `a`.`an` = `b`.`bn`;
+------+----+
| an | bn |
+------+----+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| NULL | 7 |
| NULL | 9 |
| NULL | 11 |
| NULL | 13 |
| NULL | 15 |
+------+----+

Gdzie się podział FULL OUTER JOIN?

Osoby znające SQL zauważą, że w MySQL czegoś zabrakło. FULL OUTER JOIN nie zostało zaimplementowane w MySQL, jest to połączenie RIGHT JOIN i LEFT JOIN. Aby uzyskać ten efekt będziemy musieli użyć alternatywnego rozwiązania. I w tym momencie pojawia się UNION i UNION ALL.

UNION

UNION jest operatorem teoriomnogościowym, sumuje obie kolumny, ale bez duplikatów.

mysql> select * from a
    -> left outer join b on a.an = b.bn
    -> union
    -> select * from a
    -> right outer join b on a.an = b.bn;
+------+------+
| an | bn |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | NULL |
| 8 | NULL |
| 10 | NULL |
| 12 | NULL |
| 14 | NULL |
| NULL | 7 |
| NULL | 9 |
| NULL | 11 |
| NULL | 13 |
| NULL | 15 |
+------+------+

UNION ALL

UNION ALL jest operatorem teoriomnogościowym, podobnie jak UNION sumuje obie kolumny, ale pozwala na duplikaty.

mysql> select * from a
    -> left outer join b on a.an = b.bn
    -> union all
    -> select * from a
    -> right outer join b on a.an = b.bn;
+------+------+
| an | bn |
+------+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| 6 | NULL |
| 8 | NULL |
| 10 | NULL |
| 12 | NULL |
| 14 | NULL |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
| NULL | 7 |
| NULL | 9 |
| NULL | 11 |
| NULL | 13 |
| NULL | 15 |
+------+------+

Brak komentarzy

Napisz komentarz jako pierwszy!

Zostaw odpowiedź