unionはSQLの実行結果をつなげるコマンドである。
およそ複雑なクエリを書くときに役に立つコマンドで
「A」というクエリの結果と、「B」というクエリの結果を繋げて1つの結果にしたい。
というような場合に利用する。
前提データ
employee
とskill
の2つのテーブルが存在するとする。
mysql> select * from employee;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
| 2 | Tanaka |
+----+---------+
2 rows in set (0.00 sec)
簡単な例
mysql> select * from employee where id = 1;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
+----+---------+
1 row in set (0.00 sec)
mysql> select * from employee where id = 2;
+----+--------+
| id | name |
+----+--------+
| 2 | Tanaka |
+----+--------+
1 row in set (0.00 sec)
上記2つのSQL文の結果を最終的につなげる場合、
unionを使って以下のように記述する。
mysql> select * from employee where id = 1 union select * from employee where id = 2;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
| 2 | Tanaka |
+----+---------+
2 rows in set (0.01 sec)
注意すべき制約
注意すべきは、結合対象の「A」クエリと「B」クエリの出力カラムが一致している
ということである。
例えば、以下のようなSQLでは結合することができない。
-- 全てのカラムを出力
mysql> select * from employee where id = 1;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
+----+---------+
1 row in set (0.00 sec)
-- 名前のみを出力
mysql> select name from employee where id = 2;
+--------+
| name |
+--------+
| Tanaka |
+--------+
1 row in set (0.00 sec)
-- 一方はid,nameを出力するのに対し、もう一方のSQLはnameしか出力しないのでフォーマットが合わない
mysql> select * from employee where id = 1 union select name from employee where id = 2;
ERROR 1222 (21000): The used SELECT statements have a different number of columns
union allとの違い
union
:重複データは削除するunion all
:重複データはそのままにする
同じデータを出力するクエリをunion
、union all
それぞれで書いてみるとわかりやすい。
mysql> select * from employee where id = 1 union select * from employee where id = 1;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
+----+---------+
1 row in set (0.00 sec)
mysql> select * from employee where id = 1 union all select * from employee where id = 1;
+----+---------+
| id | name |
+----+---------+
| 1 | Nagaoka |
| 1 | Nagaoka |
+----+---------+
2 rows in set (0.00 sec)