WHERE 等価結合 / INNER JOIN / LEFT OUTER JOIN / RIGHT OUTER JOIN の違い @ MariaDB

# 環境

- MariaDB 10.3.29-MariaDB-0ubuntu0.20.04.1
- Ubuntu 20.04 LTS

# シノニム

- JOIN → INNER JOIN
- LEFT JOIN → LEFT OUTER JOIN
- RIGHT JOIN → RIGHT OUTER JOIN


# テストテーブル

```

MariaDB [test]> select * from 会員;
+----+-----------------+-----------+
| id | 漢字氏名        | ランク    |
+----+-----------------+-----------+
|  1 | 白き帝王        |        10 |
|  2 | 紅き小惑星      |         1 |
|  3 | 破壊連星        |         1 |
|  4 | 聖なる眼        |      NULL |
+----+-----------------+-----------+
4 rows in set (0.000 sec)

MariaDB [test]> SELECT * FROM ランク属性;
+-----------+--------------+
| ランク    | ランク名     |
+-----------+--------------+
|         1 | 下っ端       |
|        10 | 聖帝         |
|       100 | 神           |
+-----------+--------------+
3 rows in set (0.000 sec)

```

# WHERE 等価結合 / INNER JOIN

```

MariaDB [test]> SELECT * FROM 会員,ランク属性 WHERE 会員.ランク=ランク属性.ラン ク;
+----+-----------------+-----------+-----------+--------------+
| id | 漢字氏名        | ランク    | ランク    | ランク名     |
+----+-----------------+-----------+-----------+--------------+
|  1 | 白き帝王        |        10 |        10 | 聖帝         |
|  2 | 紅き小惑星      |         1 |         1 | 下っ端       |
|  3 | 破壊連星        |         1 |         1 | 下っ端       |
+----+-----------------+-----------+-----------+--------------+
3 rows in set (0.001 sec)

MariaDB [test]> SELECT * FROM 会員 INNER JOIN ランク属性 ON 会員.ランク=ランク属性.ランク;
+----+-----------------+-----------+-----------+--------------+
| id | 漢字氏名        | ランク    | ランク    | ランク名     |
+----+-----------------+-----------+-----------+--------------+
|  1 | 白き帝王        |        10 |        10 | 聖帝         |
|  2 | 紅き小惑星      |         1 |         1 | 下っ端       |
|  3 | 破壊連星        |         1 |         1 | 下っ端       |
+----+-----------------+-----------+-----------+--------------+
3 rows in set (0.000 sec)
```
同じ結果ですね。


# LEFT OUTER JOIN / RIGHT OUTER JOIN

主テーブルを全部表示。従テーブルに該当が無い場合はNULL表示。
LEFT / RIGHT は JOIN 句の左側が主テーブルか右側が主テーブルかの違い。


```

MariaDB [test]> SELECT * FROM 会員 LEFT OUTER JOIN ランク属性 ON 会員.ランク=ラ ンク属性.ランク;
+----+-----------------+-----------+-----------+--------------+
| id | 漢字氏名        | ランク    | ランク    | ランク名     |
+----+-----------------+-----------+-----------+--------------+
|  2 | 紅き小惑星      |         1 |         1 | 下っ端       |
|  3 | 破壊連星        |         1 |         1 | 下っ端       |
|  1 | 白き帝王        |        10 |        10 | 聖帝         |
|  4 | 聖なる眼        |      NULL |      NULL | NULL         |
+----+-----------------+-----------+-----------+--------------+
4 rows in set (0.001 sec)
```
JOIN 句より左側を主テーブルとし、主テーブルを全部表示。従テーブルに該当が無い場合はNULL表示。


```

MariaDB [test]> SELECT * FROM 会員 RIGHT OUTER JOIN ランク属性 ON 会員.ランク=ランク属性.ランク;
+------+-----------------+-----------+-----------+--------------+
| id   | 漢字氏名        | ランク    | ランク    | ランク名     |
+------+-----------------+-----------+-----------+--------------+
|    1 | 白き帝王        |        10 |        10 | 聖帝         |
|    2 | 紅き小惑星      |         1 |         1 | 下っ端       |
|    3 | 破壊連星        |         1 |         1 | 下っ端       |
| NULL | NULL            |      NULL |       100 | 神           |
+------+-----------------+-----------+-----------+--------------+
4 rows in set (0.000 sec)

```
JOIN 句より右側を主テーブルとし、主テーブルを全部表示。従テーブルに該当が無い場合はNULL表示。

## テーブル位置を逆に


```

MariaDB [test]> SELECT * FROM ランク属性 RIGHT OUTER JOIN 会員 ON 会員.ランク=ランク属性.ランク;
+-----------+--------------+----+-----------------+-----------+
| ランク    | ランク名     | id | 漢字氏名        | ランク    |
+-----------+--------------+----+-----------------+-----------+
|         1 | 下っ端       |  2 | 紅き小惑星      |         1 |
|         1 | 下っ端       |  3 | 破壊連星        |         1 |
|        10 | 聖帝         |  1 | 白き帝王        |        10 |
|      NULL | NULL         |  4 | 聖なる眼        |      NULL |
+-----------+--------------+----+-----------------+-----------+
4 rows in set (0.000 sec)

MariaDB [test]> SELECT * FROM ランク属性 LEFT OUTER JOIN 会員 ON 会員.ランク=ラ ンク属性.ランク;
+-----------+--------------+------+-----------------+-----------+
| ランク    | ランク名     | id   | 漢字氏名        | ランク    |
+-----------+--------------+------+-----------------+-----------+
|        10 | 聖帝         |    1 | 白き帝王        |        10 |
|         1 | 下っ端       |    2 | 紅き小惑星      |         1 |
|         1 | 下っ端       |    3 | 破壊連星        |         1 |
|       100 | 神           | NULL | NULL            |      NULL |
+-----------+--------------+------+-----------------+-----------+
4 rows in set (0.001 sec)

```

テーブル位置を逆にしたうえで、LEFT/RIGHT を逆にすると(上記ではフィールド並びは異なりますが)先ほどと同じ結果が得られます。