Lesson 11

複雑な検索方法

Lesson 11 Chapter 1
本レッスンについて

本レッスンでは、「テーブルの結合」および「集合演算子」について学んでいきます。

テーブルの結合

テーブルの結合とは、以下の図のように、2 つのテーブルの共通となるカラムを結合条件として、値が同じレコード同士を連結するものです。

lesson11-1

テーブルの結合には、下表のように、大きく分けて 3 つの種類があります。
表を見ただけでは、イメージが湧きにくいと思いますので、今は 3 つの種類があることだけ把握できれば大丈夫です。

分類 コマンド 説明
内部結合 INNER JOIN 結合条件が一致するカラム値があるレコードのみを対象としてテーブルを結合する
外部結合 LEFT OUTER JOIN
RIGHT OUTER JOIN
FULL OUTER JOIN
結合条件が一致しないカラム値のレコードも含めてテーブルを結合する
交差結合 CROSS JOIN 全てのカラム(列)とレコード(行)の組合せを取得する

内部結合、外部結合、交差結合については、このレッスンの、Chapter 2、Chapter 3、Chapter 4 において改めて学習していきます。

集合演算子

集合演算子には、以下のようなものがあります。

分類 コマンド 説明
和演算(重複なし) UNION 複数の SELECT 結果の全ての行を加算(重複なし)
和演算(重複あり) UNION ALL 複数の SELECT 結果の全ての行を加算(重複あり)
積演算 INTERSECT 複数の SELECT 結果のうち共通の行を抽出(集合の積をとる)
差演算 EXCEPT 1つの SELECT 結果からもう1つの SELECT 結果を減算する

集合演算子については、一般的によく使用される和演算(UNION,UNION ALL)につき、Chapter 2 で学習します。
INTERSECT と EXCEPT については、MySQL でサポートされていなかったことから、ここでは割愛します(なお、最新の MySQL 8.0.31 においてサポートされるようになりました)。

集合演算子の概念を知っておくことは大事ですので、以下、それぞれの演算のイメージを、図とともに紹介いたします。

① UNION

UNION 演算子は、下図のように 2 つのテーブルのレコードを加算して取得します。
重複したレコードは、1 つのみ取得します。

lesson11-2

② UNION ALL

UNION ALL 演算子は、下図のように 2 つのテーブルのレコードを加算して取得します。
重複したレコードも含めて全て取得します。

lesson11-3

③ INTERSECT

INTERSECT 演算子は、下図のように 2 つのテーブルのレコードのうち、共通のレコードを取得します。

lesson11-4

④ EXCEPT

EXCEPT 演算子は、下図のように 1 つのテーブルから、もう 1 つのテーブルのレコードを差し引きます。
差し引かれるのは、両テーブルに共通するレコードのみです。

lesson11-5

以上、集合演算子について、講学上の説明をしました。
具体的な DB 操作は、Chapter 5(UNION,UNION ALL)を参照してください。

テーブルの準備

本レッスンで使用するテーブルを準備します。
今回も、テーブルを 2 つ作成します。練習も兼ねて、手順どおりに作成を進めてください。

データベースの選択

まず、test データベースを選択します。

PowerShell
mysql> use test;

社員テーブルの作成

それでは、次のように本レッスン用の 社員テーブル を作成しましょう。
今回は、分かりやすさを重視して日本語で作成してみます。次のように、CREATE TABLE 文、INSERT 文のコマンドを実行してください。

PowerShell
mysql> CREATE TABLE 社員 (
  社員ID int PRIMARY KEY,
  氏名 varchar(20),
  年齢 tinyint,
  部署コード varchar(8)
);

mysql> INSERT INTO 社員 VALUES
  (1, '山田太郎', 56, 'C002'),
  (2, '田中春子', 41, 'C003'),
  (3, '鈴木三郎', 24, null),
  (4, '中村夏子', 36, 'C001'),
  (5, '渡辺秋子', 25, 'C002');

mysql> SELECT * FROM 社員;
+--------+----------+------+------------+
| 社員ID | 氏名     | 年齢 | 部署コード |
+--------+----------+------+------------+
|      1 | 山田太郎 |   56 | C002       |
|      2 | 田中春子 |   41 | C003       |
|      3 | 鈴木三郎 |   24 | NULL       |
|      4 | 中村夏子 |   36 | C001       |
|      5 | 渡辺秋子 |   25 | C002       |
+--------+----------+------+------------+
5 rows in set (0.02 sec)

部署テーブルの作成

続いて、部署テーブル を作成します。
次のように、CREATE TABLE 文、INSERT 文のコマンドを実行してください。

PowerShell
mysql> CREATE TABLE 部署 (
  部署コード varchar(8) PRIMARY KEY,
  部署名 varchar(20)
);

mysql> INSERT INTO 部署 VALUES
  ('C001', '管理部'),
  ('C002', '営業部'),
  ('C003', '開発部'),
  ('C004', '事業戦略部');

mysql> SELECT * FROM 部署;
+------------+------------+
| 部署コード | 部署名     |
+------------+------------+
| C001       | 管理部     |
| C002       | 営業部     |
| C003       | 開発部     |
| C004       | 事業戦略部 |
+------------+------------+
4 rows in set (0.00 sec)

以上で、ひとまずテーブルの作成は完了です。

Lesson 11 Chapter 2
内部結合

内部結合とは、以下の図のように、結合条件が一致するカラム値があるレコードのみを対象としてテーブルを結合するものです。

lesson11-6

結合条件のカラムで一致する値が無いレコードは、取得されません。

基本構文

内部結合を行う場合は、INNER JOIN を使用します。
骨組みだけの構文を書くと次のようになります。

SELECT [カラム名] FROM [テーブル名1] INNER JOIN [テーブル名2] ON [結合条件];

内部結合を実行する

① 取得カラムを指定せずに実行

それでは、社員テーブルと部署テーブルを結合してみましょう。
先ほどの基本構文に合わせて、次のように SQL を作成します。 取得カラム名は指定せず、アスタリスク (*) としておきます。

PowerShell
SELECT * FROM 社員 INNER JOIN 部署 ON 社員.部署コード = 部署.部署コード;

結合条件は 社員.部署コード = 部署.部署コード と指定しています。
以前も出てきましたが、1 つの SELECT 文で 2 つ以上のテーブルを使用する場合は、テーブル名とカラム名を . で繋げて指定する必要があります。

それでは、実際に SQL を実行して確認してみましょう。

PowerShell
mysql> SELECT * FROM 社員 INNER JOIN 部署 ON 社員.部署コード = 部署.部署コード;
+--------+----------+------+------------+------------+--------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署コード | 部署名 |
+--------+----------+------+------------+------------+--------+
|      1 | 山田太郎 |   56 | C002       | C002       | 営業部 |
|      2 | 田中春子 |   41 | C003       | C003       | 開発部 |
|      4 | 中村夏子 |   36 | C001       | C001       | 管理部 |
|      5 | 渡辺秋子 |   25 | C002       | C002       | 営業部 |
+--------+----------+------+------------+------------+--------+
4 rows in set (0.00 sec)

実行すると、以上のように結合テーブルを取得することができます。
ただし、2 つのテーブルの部署コードが重複して表示されてしまいます。
同名のカラム名があると、DBMS によってはエラーとなる場合もありますので、あまり良い方法とはいえません。

② 取得カラムを指定して実行する

次に、取得カラム名を指定して実行してみましょう。次のように SQL を作成して実行してみてください。
SQL 文が長くなってしまいましたが、指定内容自体はさほど難しくはないものと思います。

PowerShell
mysql> SELECT
  社員.社員ID AS 社員ID,
  社員.氏名 AS 氏名,
  社員.年齢 AS 年齢,
  部署.部署コード AS 部署コード,
  部署.部署名 AS 部署名
FROM 社員
INNER JOIN 部署
ON 社員.部署コード = 部署.部署コード;
+--------+----------+------+------------+--------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署名 |
+--------+----------+------+------------+--------+
|      1 | 山田太郎 |   56 | C002       | 営業部 |
|      2 | 田中春子 |   41 | C003       | 開発部 |
|      4 | 中村夏子 |   36 | C001       | 管理部 |
|      5 | 渡辺秋子 |   25 | C002       | 営業部 |
+--------+----------+------+------------+--------+
4 rows in set (0.00 sec)

以上のように、本 Chapter の冒頭に示した図と同じテーブルを取得することができました。

③ 取得条件を指定して実行する

INNER JOIN を使用しても、SELECT 文は普段通りに WHERE 句や ORDER BY 句などの指定ができます。
次に INNER JOIN とともに WHERE 句を使用して、部署コードが C002 のレコードに限定して取得してみましょう。
WHERE 句を使用する場合は、次のような構文となります。

SELECT [カラム名] FROM [テーブル名1] INNER JOIN [テーブル名2] ON [結合条件] WHERE [抽出条件];

次のように、SQL 文を記載して実行してみてください。

PowerShell
mysql> SELECT
  社員.社員ID AS 社員ID,
  社員.氏名 AS 氏名,
  社員.年齢 AS 年齢,
  部署.部署コード AS 部署コード,
  部署.部署名 AS 部署名
FROM 社員
INNER JOIN 部署
ON 社員.部署コード = 部署.部署コード
WHERE 社員.部署コード = 'C002';
+--------+----------+------+------------+--------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署名 |
+--------+----------+------+------------+--------+
|      1 | 山田太郎 |   56 | C002       | 営業部 |
|      5 | 渡辺秋子 |   25 | C002       | 営業部 |
+--------+----------+------+------------+--------+
2 rows in set (0.02 sec)

以上のように、WHERE 句で条件指定したとおりにレコードが取得できれば OK です。

Lesson 11 Chapter 3
外部結合

外部結合は、内部結合とは異なり、結合条件が一致しないカラム値のレコードも含めてテーブルを結合するものです。

外部結合の種類

外部結合の種類として、次の 3 つがあります。

  • 左外部結合(LEFT OUTER JOIN)
  • 右外部結合(RIGHT OUTER JOIN)
  • 完全外部結合(FULL OUTER JOIN)

言葉だけでは分かりにくいので、以下、図を見ながら 1 つずつ確認していきましょう。
なお、完全外部結合については、現時点では、MySQL でサポートされていないため、ここでは概略の紹介だけにとどめます。

左外部結合(LEFT OUTER JOIN)

左外部結合は、先に指定したテーブル(式の左側のテーブル)のレコードは全て取得し、後に指定したテーブル(式の右側のテーブル)については、左テーブルと一致するレコードのみ取得するものです。
イメージとして、次の図のような結合になります。

lesson11-7

基本構文

左外部結合を行う場合は、LEFT OUTER JOIN を使用します(OUTER は省略できるため LEFT JOIN でも構いません)。
骨組みだけの構文は次のようになります。

SELECT [カラム名] FROM [テーブル名1] LEFT OUTER JOIN [テーブル名2] ON [結合条件];

① シンプルな構文で実行する

それでは、社員テーブルと部署テーブルについて、左外部結合をしてみましょう。
先ほどの基本構文に合わせて、次のように SQL を作成します。構文は INNER JOIN のときとほぼ同じです。

PowerShell
 SELECT
  社員.社員ID AS 社員ID,
  社員.氏名 AS 氏名,
  社員.年齢 AS 年齢,
  部署.部署コード AS 部署コード,
  部署.部署名 AS 部署名
FROM 社員
LEFT OUTER JOIN 部署
ON 社員.部署コード = 部署.部署コード;

それでは、実際に SQL を実行して確認してみましょう。

PowerShell
mysql> SELECT
  社員.社員ID AS 社員ID,
  社員.氏名 AS 氏名,
  社員.年齢 AS 年齢,
  部署.部署コード AS 部署コード,
  部署.部署名 AS 部署名
FROM 社員
LEFT OUTER JOIN 部署
ON 社員.部署コード = 部署.部署コード;
+--------+----------+------+------------+--------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署名 |
+--------+----------+------+------------+--------+
|      4 | 中村夏子 |   36 | C001       | 管理部 |
|      1 | 山田太郎 |   56 | C002       | 営業部 |
|      5 | 渡辺秋子 |   25 | C002       | 営業部 |
|      2 | 田中春子 |   41 | C003       | 開発部 |
|      3 | 鈴木三郎 |   24 | NULL       | NULL   |
+--------+----------+------+------------+--------+
5 rows in set (0.00 sec)

実行すると、以上のように結合テーブルを取得することができます。
内部結合では取得できなかった 社員ID = 3 のレコードも取得できています。部署名は存在しないため NULL となっているのが分かると思います。
ただ、取得順がバラバラになってしまったので、次に、ORDER BY 句を使って実行してみましょう。

② 取得順序を指定して実行する

LEFT OUTER JOIN を使用しても、SELECT 文は普段通りに WHERE 句や ORDER BY 句などの指定ができます。
次に LEFT OUTER JOIN とともに ORDER BY 句使用して、レコードを並べ替えて取得してみましょう。

次のように、SQL 文を記載して実行してみてください。
LEFT OUTER JOINLEFT JOIN に省略し、併せて AS 句も省略しています。

PowerShell
mysql> SELECT
  社員.社員ID 社員ID,
  社員.氏名 氏名,
  社員.年齢 年齢,
  部署.部署コード 部署コード,
  部署.部署名 部署名
FROM 社員
LEFT JOIN 部署
ON 社員.部署コード = 部署.部署コード
ORDER BY 社員.社員ID;
+--------+----------+------+------------+--------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署名 |
+--------+----------+------+------------+--------+
|      1 | 山田太郎 |   56 | C002       | 営業部 |
|      2 | 田中春子 |   41 | C003       | 開発部 |
|      3 | 鈴木三郎 |   24 | NULL       | NULL   |
|      4 | 中村夏子 |   36 | C001       | 管理部 |
|      5 | 渡辺秋子 |   25 | C002       | 営業部 |
+--------+----------+------+------------+--------+
5 rows in set (0.02 sec)

以上のように、ORDER BY 句で指定したとおりの順でレコードを取得することができました。

右外部結合(RIGHT OUTER JOIN)

右外部結合は、先に指定したテーブル(左テーブル)のレコードは、結合条件が右テーブルに含まれるレコードのみ取得し、後に指定したテーブル(右テーブル)については全て取得するものです。
イメージとして、次の図のような結合になります。

lesson11-8

基本構文

右外部結合を行う場合は、RIGHT OUTER JOIN を使用します(OUTER は省略できるため RIGHT JOIN でも構いません)。
骨組みだけの構文は次のようになります。

SELECT [カラム名] FROM [テーブル名1] RIGHT OUTER JOIN [テーブル名2] ON [結合条件];

では、社員テーブルと部署テーブルについて、右外部結合をしてみましょう。
次のように SQL を作成して実行してみてください。

PowerShell
mysql> SELECT
  社員.社員ID AS 社員ID,
  社員.氏名 AS 氏名,
  社員.年齢 AS 年齢,
  部署.部署コード AS 部署コード,
  部署.部署名 AS 部署名
FROM 社員
RIGHT OUTER JOIN 部署
ON 社員.部署コード = 部署.部署コード;
+--------+----------+------+------------+------------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署名     |
+--------+----------+------+------------+------------+
|      1 | 山田太郎 |   56 | C002       | 営業部     |
|      2 | 田中春子 |   41 | C003       | 開発部     |
|      4 | 中村夏子 |   36 | C001       | 管理部     |
|      5 | 渡辺秋子 |   25 | C002       | 営業部     |
|   NULL | NULL     | NULL | C004       | 事業戦略部 |
+--------+----------+------+------------+------------+
5 rows in set (0.00 sec)

ここでは 部署コード = 'C004' のレコードが取得できています。
結合する社員テーブルのレコードはしないため、それらのカラムが NULL となっていることが確認できます。

完全外部結合(FULL OUTER JOIN)

完全外部結合では、先に指定したテーブル(左テーブル)と、後に指定したテーブル(右テーブル)の全てのレコードを取得します。
イメージとして、次の図のような結合になります。

lesson11-9

完全外部結合は、MySQL でサポートされていないため、紹介のみで終わります。
さほど使用する機会も少ないと思われますが、このような結合があることも把握しておきましょう。

Lesson 11 Chapter 4
交差結合

交差結合(CROSS JOIN)とは、以下の図のように、全てのカラム(列)とレコード(行)の組合せを取得するものです。
全ての組合せを取得するため、結合条件はありません。
交差結合は「クロス結合」とも呼ばれています。

lesson11-10

上図のように、5 レコードのテーブルと、4 レコードのテーブルを結合すると、5 × 4 で、計 20 件のレコードが取得されます。

基本構文

交差結合を行う場合は、CROSS JOIN を使用します。
骨組みだけの構文を書くと次のようになります。

SELECT [カラム名] FROM [テーブル名1] CROSS JOIN [テーブル名2];

交差結合を実行する

CROSS JOIN の実行

それでは、社員テーブルと部署テーブルを交差結合してみましょう。
早速、次のように SQL を実行してみてください。

PowerShell
mysql> SELECT * FROM 社員 CROSS JOIN 部署;
+--------+----------+------+------------+------------+------------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署コード | 部署名     |
+--------+----------+------+------------+------------+------------+
|      1 | 山田太郎 |   56 | C002       | C001       | 管理部     |
|      1 | 山田太郎 |   56 | C002       | C002       | 営業部     |
|      1 | 山田太郎 |   56 | C002       | C003       | 開発部     |
|      1 | 山田太郎 |   56 | C002       | C004       | 事業戦略部 |
|      2 | 田中春子 |   41 | C003       | C001       | 管理部     |
|      2 | 田中春子 |   41 | C003       | C002       | 営業部     |
|      2 | 田中春子 |   41 | C003       | C003       | 開発部     |
|      2 | 田中春子 |   41 | C003       | C004       | 事業戦略部 |
|      3 | 鈴木三郎 |   24 | NULL       | C001       | 管理部     |
|      3 | 鈴木三郎 |   24 | NULL       | C002       | 営業部     |
|      3 | 鈴木三郎 |   24 | NULL       | C003       | 開発部     |
|      3 | 鈴木三郎 |   24 | NULL       | C004       | 事業戦略部 |
|      4 | 中村夏子 |   36 | C001       | C001       | 管理部     |
|      4 | 中村夏子 |   36 | C001       | C002       | 営業部     |
|      4 | 中村夏子 |   36 | C001       | C003       | 開発部     |
|      4 | 中村夏子 |   36 | C001       | C004       | 事業戦略部 |
|      5 | 渡辺秋子 |   25 | C002       | C001       | 管理部     |
|      5 | 渡辺秋子 |   25 | C002       | C002       | 営業部     |
|      5 | 渡辺秋子 |   25 | C002       | C003       | 開発部     |
|      5 | 渡辺秋子 |   25 | C002       | C004       | 事業戦略部 |
+--------+----------+------+------------+------------+------------+
20 rows in set (0.00 sec)

図で示した内容と同様のレコードを取得することができました。

FROM 句に 2 つのテーブルを指定する

FROM 句に 2 つのテーブルを指定するだけでも、CROSS JOIN と同じ結果を取得することができます。
次のように実行してみてください。

PowerShell
mysql> SELECT * FROM 社員, 部署;
+--------+----------+------+------------+------------+------------+
| 社員ID | 氏名     | 年齢 | 部署コード | 部署コード | 部署名     |
+--------+----------+------+------------+------------+------------+
|      1 | 山田太郎 |   56 | C002       | C001       | 管理部     |
|      1 | 山田太郎 |   56 | C002       | C002       | 営業部     |
|      1 | 山田太郎 |   56 | C002       | C003       | 開発部     |
|      1 | 山田太郎 |   56 | C002       | C004       | 事業戦略部 |
|      2 | 田中春子 |   41 | C003       | C001       | 管理部     |
|      2 | 田中春子 |   41 | C003       | C002       | 営業部     |
|      2 | 田中春子 |   41 | C003       | C003       | 開発部     |
|      2 | 田中春子 |   41 | C003       | C004       | 事業戦略部 |
|      3 | 鈴木三郎 |   24 | NULL       | C001       | 管理部     |
|      3 | 鈴木三郎 |   24 | NULL       | C002       | 営業部     |
|      3 | 鈴木三郎 |   24 | NULL       | C003       | 開発部     |
|      3 | 鈴木三郎 |   24 | NULL       | C004       | 事業戦略部 |
|      4 | 中村夏子 |   36 | C001       | C001       | 管理部     |
|      4 | 中村夏子 |   36 | C001       | C002       | 営業部     |
|      4 | 中村夏子 |   36 | C001       | C003       | 開発部     |
|      4 | 中村夏子 |   36 | C001       | C004       | 事業戦略部 |
|      5 | 渡辺秋子 |   25 | C002       | C001       | 管理部     |
|      5 | 渡辺秋子 |   25 | C002       | C002       | 営業部     |
|      5 | 渡辺秋子 |   25 | C002       | C003       | 開発部     |
|      5 | 渡辺秋子 |   25 | C002       | C004       | 事業戦略部 |
+--------+----------+------+------------+------------+------------+
20 rows in set (0.00 sec)

CROSS JOIN と同じ結果を取得することができました。

Lesson 11 Chapter 5
集合演算子

本レッスンの冒頭でも説明しましたが、集合演算子には、以下のようなものがあります。

分類 コマンド 説明
和演算(重複なし) UNION 複数の SELECT 結果の全ての行を加算(重複なし)
和演算(重複あり) UNION ALL 複数の SELECT 結果の全ての行を加算(重複あり)
積演算 INTERSECT 複数の SELECT 結果のうち共通の行を抽出(集合の積をとる)
差演算 EXCEPT 1つの SELECT 結果からもう1つの SELECT 結果を減算する

ここでは、よく使用する「UNION」と「UNION ALL」について確認していきましょう。

UNION 演算子

UNION 演算子は、下図のように 2 つのテーブルのレコードを加算して取得します。
重複したレコードは、1 つのみ取得します。

lesson11-2

本 Chapter で使用するテーブルの作成

SQL を実行するために、上にある「社員テーブルA」と「社員テーブルB」の 2 つのテーブルを実際に作成しておきます。
まず、次のように、CREATE TABLE 文、INSERT 文を実行して 社員A テーブルを作成してください。

PowerShell
mysql> CREATE TABLE 社員A (
  社員ID varchar(8) PRIMARY KEY,
  氏名 varchar(20),
  年齢 tinyint
);

mysql> INSERT INTO 社員A VALUES
  ('A001', '山田太郎', 56),
  ('B006', '田中春子', 41),
  ('B007', '鈴木三郎', 24);

mysql> SELECT * FROM 社員A;
+--------+----------+------+
| 社員ID | 氏名     | 年齢 |
+--------+----------+------+
| A001   | 山田太郎 |   56 |
| B006   | 田中春子 |   41 |
| B007   | 鈴木三郎 |   24 |
+--------+----------+------+
3 rows in set (0.00 sec)

同様に 社員B テーブルも作成しましょう。

PowerShell
mysql> CREATE TABLE 社員B (
  社員ID varchar(8) PRIMARY KEY,
  氏名 varchar(20),
  年齢 tinyint
);

mysql> INSERT INTO 社員B VALUES
  ('A001', '山田太郎', 56),
  ('C003', '川田夏子', 36),
  ('C004', '渡辺秋子', 25);

mysql> SELECT * FROM 社員B;
+--------+----------+------+
| 社員ID | 氏名     | 年齢 |
+--------+----------+------+
| A001   | 山田太郎 |   56 |
| C003   | 川田夏子 |   36 |
| C004   | 渡辺秋子 |   25 |
+--------+----------+------+
3 rows in set (0.00 sec)

基本構文

UNION 演算子の構文を、骨組みだけで書くと次のようになります。

SELECT [カラム名] FROM [テーブル名1]
UNION
SELECT [カラム名] FROM [テーブル名2];

SELECT 文と SELECT 文を UNION で結合するだけです。
SELECT 文には、通常通り WHERE 句などを使用することができます。
なお、各テーブルから抽出するカラム名とデータ型は一致している必要があります(カラム名とデータ型が一致していれば、異なる構造のテーブル同士でも UNION 演算子で結合することができます)。

単純に結合する

それでは、実際に UNION 演算子を使用して、テーブルを結合させてみましょう。
次のように SQL を指定して実行してください。

PowerShell
mysql> SELECT * FROM 社員A UNION SELECT * FROM 社員B;
+--------+----------+------+
| 社員ID | 氏名     | 年齢 |
+--------+----------+------+
| A001   | 山田太郎 |   56 |
| B006   | 田中春子 |   41 |
| B007   | 鈴木三郎 |   24 |
| C003   | 川田夏子 |   36 |
| C004   | 渡辺秋子 |   25 |
+--------+----------+------+
5 rows in set (0.02 sec)

実行すると、以上のように 2 つのテーブルが結合されました。
双方のテーブルに存在していた「山田太郎」のレコードは、重複することなく、1 つのみ取得されています。

カラム名を指定して結合する

次に、カラム名を指定して、テーブルを結合させてみましょう。
次のように SQL を指定して実行してください。

PowerShell
mysql> SELECT 社員ID AS ID, 氏名 FROM 社員A UNION SELECT 社員ID AS ID, 氏名 FROM 社員B;
+------+----------+
| ID   | 氏名     |
+------+----------+
| A001 | 山田太郎 |
| B006 | 田中春子 |
| B007 | 鈴木三郎 |
| C003 | 川田夏子 |
| C004 | 渡辺秋子 |
+------+----------+
5 rows in set (0.00 sec)

以上のようにカラム名を指定して、テーブルを結合することができました。
カラム名に別名を付けられる AS 句を使用したりすることで、カラム名の異なるテーブルでも結合できるようにすることも可能になります。

UNION ALL 演算子

UNION ALL 演算子は、下図のように 2 つのテーブルのレコードを加算して取得します。
重複したレコードも含めて全て取得します。

lesson11-3

基本構文

UNION ALL 演算子の構文を、骨組みだけで書くと次のようになります。

SELECT [カラム名] FROM [テーブル名1]
UNION ALL
SELECT [カラム名] FROM [テーブル名2];

UNION 演算子と同じ構造で、SELECT 文と SELECT 文を UNION ALL で結合するだけです。

UNION ALL で結合する

それでは、実際に UNION ALL 演算子を使用して、テーブルを結合させてみましょう。
次のように SQL を指定して実行してください。

PowerShell
mysql> SELECT * FROM 社員A UNION ALL SELECT * FROM 社員B;
+--------+----------+------+
| 社員ID | 氏名     | 年齢 |
+--------+----------+------+
| A001   | 山田太郎 |   56 |
| B006   | 田中春子 |   41 |
| B007   | 鈴木三郎 |   24 |
| A001   | 山田太郎 |   56 |
| C003   | 川田夏子 |   36 |
| C004   | 渡辺秋子 |   25 |
+--------+----------+------+
6 rows in set (0.00 sec)

以上のように 2 つのテーブルが結合されました。
双方のテーブルに存在していた「山田太郎」のレコードが、そのまま重複して取得されています。
それ以外は、UNION 演算子と相違ありません。

以上、本レッスンでは「複雑な検索方法」について学習をしました。
INNER JOIN や OUTER JOIN を使用したテーブル結合は、実際の開発においても多用しますので、分からなければ振り返って学習しつつ、自分のものとしていただければと思います。