【SQL】unionの使い方

データベースサーバーのイメージ画像 データベース

unionはSQLの実行結果をつなげるコマンドである。

およそ複雑なクエリを書くときに役に立つコマンドで
「A」というクエリの結果と、「B」というクエリの結果を繋げて1つの結果にしたい。
というような場合に利用する。

前提データ

employeeskillの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:重複データはそのままにする

同じデータを出力するクエリをunionunion 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)
タイトルとURLをコピーしました