Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

MySQLのunionの使い方について、サンプルSQLを使ってまとめました。

以下、データベースとして、MySQLのサンプルデータベースEmployeesを使っています。

サンプルデータベースのインストール方法は、下記を参考にしてください。

【関連記事】
MySQLの入門には、GUIツールで慣れ、サンプルDBを使った学習が効果的

MySQLのUNIONの構文

SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]

参考)MySQL :: MySQL 5.6 リファレンスマニュアル :: 13.2.9.4 UNION 構文

複数のselect文の結果を1つの結果に統合するためのステートメントです。2つめ以降の結果は、1つめの結果と同じデータ型にする必要があります。データ型さえ合っていれば、異なるテーブルのselect結果でもunionが使用可能です。

ファイル出力を行うinto outfileは、最後のselect文にのみ使用可能。

SQL99(SQL3)に準拠したSQL標準のステートメントです。特にMySQL独自の拡張はないようです。

【関連記事】
SQLとはどういうもの? 独自拡張と標準SQLの大きな違いって、何?

select * from employees where emp_no < 10005
union select * from employees where emp_no between 10007 and 10010;

上記SQLは、employeesテーブルから、emp_no<10005の行と、emp_noが10007~10010の行をselectして結合するSQLです。実行結果はこうなります。

+--------+------------+------------+-----------+--------+------------+
| emp_no | birth_date | first_name | last_name | gender | hire_date  |
+--------+------------+------------+-----------+--------+------------+
|  10001 | 1953-09-02 | Georgi     | Facello   | M      | 1986-06-26 |
|  10002 | 1964-06-02 | Bezalel    | Simmel    | F      | 1985-11-21 |
|  10003 | 1959-12-03 | Parto      | Bamford   | M      | 1986-08-28 |
|  10004 | 1954-05-01 | Chirstian  | Koblick   | M      | 1986-12-01 |
|  10007 | 1957-05-23 | Tzvetan    | Zielinski | F      | 1989-02-10 |
|  10008 | 1958-02-19 | Saniya     | Kalloufi  | M      | 1994-09-15 |
|  10009 | 1952-04-19 | Sumant     | Peac      | F      | 1985-02-18 |
|  10010 | 1963-06-01 | Duangkaew  | Piveteau  | F      | 1989-08-24 |
+--------+------------+------------+-----------+--------+------------+
8 rows in set (0.00 sec)

MySQLのunionサンプルSQLコード

union allの前に、select文ごとにorder byを実行する方法

複数のselect文ごとにorder byでソートをするには、それぞれのselect文を括弧で囲み、limitを合わせて指定する必要があります。

mysql> (select * from employees where emp_no <= 10010 order by birth_date limit 10) 
UNION ALL
 ( select * from employees where emp_no between 10011 and 10020 order by first_name limit 10);

上記のSQLは、employees(雇用者テーブル)のうち、emp_noが10010以下の10件をbirth_date(誕生日)でソートし、emp_noが1011~10020の10件をfirst_name(姓名の名)でソートして結合します。

実行結果はこうなります。

+--------+------------+------------+-------------+--------+------------+
| emp_no | birth_date | first_name | last_name   | gender | hire_date  |
+--------+------------+------------+-------------+--------+------------+
|  10009 | 1952-04-19 | Sumant     | Peac        | F      | 1985-02-18 |
|  10006 | 1953-04-20 | Anneke     | Preusig     | F      | 1989-06-02 |
|  10001 | 1953-09-02 | Georgi     | Facello     | M      | 1986-06-26 |
|  10004 | 1954-05-01 | Chirstian  | Koblick     | M      | 1986-12-01 |
|  10005 | 1955-01-21 | Kyoichi    | Maliniak    | M      | 1989-09-12 |
|  10007 | 1957-05-23 | Tzvetan    | Zielinski   | F      | 1989-02-10 |
|  10008 | 1958-02-19 | Saniya     | Kalloufi    | M      | 1994-09-15 |
|  10003 | 1959-12-03 | Parto      | Bamford     | M      | 1986-08-28 |
|  10010 | 1963-06-01 | Duangkaew  | Piveteau    | F      | 1989-08-24 |
|  10002 | 1964-06-02 | Bezalel    | Simmel      | F      | 1985-11-21 |
|  10014 | 1956-02-12 | Berni      | Genin       | M      | 1987-03-11 |
|  10017 | 1958-07-06 | Cristinel  | Bouloucos   | F      | 1993-08-03 |
|  10013 | 1963-06-07 | Eberhardt  | Terkki      | M      | 1985-10-20 |
|  10015 | 1959-08-19 | Guoxiang   | Nooteboom   | M      | 1987-07-02 |
|  10018 | 1954-06-19 | Kazuhide   | Peha        | F      | 1987-04-03 |
|  10016 | 1961-05-02 | Kazuhito   | Cappelletti | M      | 1995-01-27 |
|  10019 | 1953-01-23 | Lillian    | Haddadi     | M      | 1999-04-30 |
|  10011 | 1953-11-07 | Mary       | Sluis       | F      | 1990-01-22 |
|  10020 | 1952-12-24 | Mayuko     | Warwick     | M      | 1991-01-26 |
|  10012 | 1960-10-04 | Patricio   | Bridgland   | M      | 1992-12-18 |
+--------+------------+------------+-------------+--------+------------+
20 rows in set (0.00 sec)

limitなしでorder byを指定した場合は、ソート条件は無視されます。また、UNION ALLではなくUNIONを使用した場合も強制的にソートされるため、注意しましょう。

unionで結合したクエリをjoinする方法

mysql> select Q1.emp_no, first_name, last_name, dept_name from
(select emp_no, first_name, last_name from employees where emp_no < 10010 
union all
select 10100, 'yamada', 'tarou') Q1
left join dept_emp on Q1.emp_no = dept_emp.emp_no
left join departments on dept_emp.dept_no = departments.dept_no;

unionで結合したselect文を括弧で囲んでサブクエリにすることでjoin可能です。

上記のSQLは、emp_noが10010より小さいemployeesのレコードと、emp_no=10100、first_name=’yamada’、last_name=’tarou’というデータをunionで結合し、dept_emp(部署・雇用者紐付けテーブル)と、departments(部署テーブル)をjoinしています。

実行結果は以下のようになります。

+--------+------------+-----------+--------------------+
| emp_no | first_name | last_name | dept_name          |
+--------+------------+-----------+--------------------+
|  10001 | Georgi     | Facello   | Development        |
|  10002 | Bezalel    | Simmel    | Sales              |
|  10003 | Parto      | Bamford   | Production         |
|  10004 | Chirstian  | Koblick   | Production         |
|  10005 | Kyoichi    | Maliniak  | Human Resources    |
|  10006 | Anneke     | Preusig   | Development        |
|  10007 | Tzvetan    | Zielinski | Research           |
|  10008 | Saniya     | Kalloufi  | Development        |
|  10009 | Sumant     | Peac      | Quality Management |
|  10100 | yamada     | tarou     | Human Resources    |
+--------+------------+-----------+--------------------+
10 rows in set (0.00 sec)

unionで仮想的な連番テーブルを生成する方法

mysql> SELECT @seq := 1 AS seq 
UNION SELECT @seq := @seq + 1 AS seq from employees LIMIT 15;

fromで指定しているemployeesは、テーブルの件数を擬似的なループのために利用しています。十分なデータ件数があるテーブルであれば何でも構いません。

実行するとこうなります。

+------+
| seq  |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
|   10 |
|   11 |
|   12 |
|   13 |
|   14 |
|   15 |
+------+
15 rows in set (0.23 sec)

ただし、件数の少ないdepartmentsテーブル(9件)をfromに指定するとこうなります。

+------+
| seq  |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
|   10 |
+------+
10 rows in set (0.00 sec)

9回のループで、生成される連番は10までとなります。

まとめ

ポテパンダの一言メモ
  • UNIONは、select文の結果を結合できる
  • UNIONは、結果を自動的にソートする。ソートしたくない場合は、UNION ALLを使う。
  • UNION ALLでORDER BYを使う場合は、LIMITを指定する。指定しないと自動ソートされる。
  • UNIONしたクエリをJOINするには、括弧で囲んでサブクエリ化する。
  • UNIONで連番テーブルを生成する場合、fromで指定するテーブルには十分な件数のあるものを選ぶ。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。