UNION と UNION ALL で結合
UNION と UNION ALL で結合
前回 「 JOIN (結合) を使いこなそう 」 では、JOIN を使って、二つ以上のテーブルからデータを取得しました。
JOIN の結合は、カラムを複数のテーブルから取得するような方向でしたが、今回は UNION を使って、複数のテーブルから取得した結果セットをひとつに結合してみましょう。
UNION 演算子
UNION は、複数の結果セットをひとつの結果セットに結合してくれるオペレータで、構文は次の通りです。
[ クエリー 1 ] UNION (ALL) [ クエリー 2 ] ( UNION ALL [ クエリー 3 ] ...)
結合するそれぞれのクエリーは、カラムの数、順番、データ型が一致していなければなりません。
ただデータ型については、変換できるものであれば完全に一致していなくても、暗黙に変換が可能なものであれば勝手に変換されます。
UNION とだけ指定すると、重複する行は削除されてユニークな値のみが結果セットに含まれます。
UNION ALL と指定すると、重複した行も結果セットに含まれます。
UNION は UNION ALL よりもクエリーコストが高いので、パフォーマンスのことを考えると、必要がない限り、できるだけ UNION ALL を使ったほうが良いです。
結合の結果セットの並び順を指定したい時には ORDER BY 句を 最後のクエリー に指定します。
WHERE、GROUP BY、HAVING 句は、ひとつひとつのクエリに指定可能です。
UNION と UNION ALL を使ってみよう!
それでは、UNION と UNION ALL を使ってみましょう。
次のような Users テーブルと Students テーブルがあります。 そのうち二人がどちらのテーブルにも存在しています。
FirstName と LastName カラムを取得する SELECT 文を UNION を使って結合し、LastName 順にならべると次のようになります。
SELECT FirstName, LastName FROM Users UNION SELECT FirstName, LastName FROM Students ORDER BY LastName;
[ 実行結果 ]
結果セットのレコード数は 9 で、重複している二人がそれぞれ 1 行ずつになって表示されています。
これを UNION ALL に変更して実行すると次のようになります。
SELECT FirstName, LastName FROM Users UNION ALL SELECT FirstName, LastName FROM Students ORDER BY LastName;
[ 実行結果 ]
結果セットのレコード数は 11 で、重複していてもそのまま表示されていますね。
上の二つのようなクエリーは、UNION を使うか UNION ALL を使うかで結果が違いますが、次のようなクエリーはどちらを使っても結果は同じです。
そういう時は UNION ALL を使うようにしましょう。
また、上の結果を見てもわかるように、カラム名は一つ目のクエリーで指定したものが採用されます。
最後に、結合した結果セットから、テンポラリーテーブルを生成したい時は、一つ目のクエリーに INTO を指定することで生成できます。