MySQL の UNION / UNION ALL
ここでは MySQL の UNION と UNION ALL についてご説明します。
MySQL の UNION の基本
MySQL の UNION は複数の結果セットをひとつの結果セットに結合する演算子です。
UNION は結合する SELECT 文の間に追加し、次のように使います。
SELECT カラム名1-1,
カラム名1-2,
...
FROM テーブル名1
WHERE ...
UNION
SELECT カラム名2-1,
カラム名2-2,
...
FROM テーブル名2
WHERE ...;
上の例では二つの SELECT 文から得られる結果セットを UNION で結合していますが、この後に更に UNION + SELECT 文を追加して、複数の結果セットを結合することもできます。
結合された結果セットのカラム名は、一番最初の結果セットのものが使われます。
結合するそれぞれの結果セットは、カラムの数、順番、データ型が一致していなければなりません。
ただ、データ型については、完全に一致していなくても、暗黙に変換が可能なものであれば変換されます。
UNION を使うと、重複する行は削除されてユニークな値のみが結果セットに含まれます。
WHERE、GROUP BY、HAVING 句は、ひとつひとつの SELECT 文に指定可能です。
結合の結果セットの並び順を指定したい時には ORDER BY 句を 最後の SELECT 文の後に指定します。
MySQL の UNION で結合する
それでは、実際に UNION で結果セットを結合してみましょう。
次のような students テーブルと users テーブルがあり、そのうち二人がどちらのテーブルにも存在しています。
実際にスクリプトを実行してみたい方は、こちら のスクリプトを実行して school_db データベースを作成して追加で、以下 users テーブルとデータを生成してお使いください。
CREATE TABLE users (
users_id INT NOT NULL AUTO_INCREMENT,
name_first VARCHAR(50) NOT NULL,
name_last VARCHAR(50) NOT NULL,
age INT,
PRIMARY KEY (users_id)
);
INSERT INTO users
(name_first, name_last, age)
VALUES
('Hana', 'Yamada', 17),
('Yuri', 'Sasaki', 15),
('Hikari', 'Yamashita', 20),
('Mana', 'Saito', 24),
('Sakura', 'Hata', 19);
この students と users テーブルから、氏名を取得する SELECT 文を UNION を使って結合し、苗字順にならべるには次のようにできます。
ORDER BY では一番最初の SELETC 文のカラム名で指定しています。
SELECT first_name,
last_name
FROM students
UNION
SELECT name_first,
name_last
FROM users
ORDER BY last_name;
[実行結果]
結果セットのレコード数は 9 で、重複している二人がそれぞれ 1 行ずつになっています。
MySQL の UNION ALL で結合する
UNION を使うと、重複する行は削除されてユニークな値のみが結果セットに含まれました。
UNION の代わりに UNION ALL と指定すると、重複した行も結果セットに含まれます。
UNION は UNION ALL よりもクエリーコストが高いので、重複レコードが存在してもよい時や、どちらを使っても結果が同じになるような場合は、UNION ALL を使ったほうが良いと思います。
先ほどのクエリーの UNION を UNION ALL にして実行すると次のようになります。
SELECT first_name,
last_name
FROM students
UNION ALL
SELECT name_first,
name_last
FROM users
ORDER BY last_name;
[実行結果]
結果セットのレコード数は 11 で、重複している二人のレコードがそのまま結果セットに含まれていますね。
以上、MySQL の UNION と UNION ALL についてご説明しました。