Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


13.2.9.4 UNION 構文

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

UNION は、複数の SELECT ステートメントからの結果を 1 つの結果セットに結合するために使用されます。

最初の SELECT ステートメントからのカラム名が、返される結果のカラム名として使用されます。各 SELECT ステートメントの対応する位置にリストされている選択されるカラムは、データ型が同じになるようにしてください。(たとえば、最初のステートメントによって選択される最初のカラムが、ほかのステートメントによって選択される最初のカラムと型が同じになるようにしてください。)

対応する SELECT カラムのデータ型が一致しない場合、UNION の結果内のカラムの型と長さは、すべての SELECT ステートメントによって取得された値を考慮に入れて決定されます。たとえば、次の例を考えてみます。

mysql> SELECT REPEAT('a',1) UNION SELECT REPEAT('b',10);
+---------------+
| REPEAT('a',1) |
+---------------+
| a             |
| bbbbbbbbbb    |
+---------------+

これらの SELECT ステートメントは通常の選択ステートメントですが、次の制限があります。

  • INTO OUTFILE を使用できるのは、最後の SELECT ステートメントだけです。(ただし、UNION の結果全体がファイルに書き込まれます。)

  • HIGH_PRIORITY を、UNION の一部である SELECT ステートメントで使用することはできません。それを最初の SELECT に対して指定しても、何の効果もありません。それを以降のいずれかの SELECT ステートメントに対して指定すると、構文エラーが発生します。

UNION のデフォルトの動作では、重複した行が結果から削除されます。オプションの DISTINCT キーワードは、これも重複した行の削除を指定するため、デフォルト以外の効果は何もありません。オプションの ALL キーワードを指定すると、重複した行の削除は実行されず、その結果には、すべての SELECT ステートメントからの一致するすべての行が含まれます。

UNION ALLUNION DISTINCT を同じクエリー内で混在させることができます。混在した UNION 型は、DISTINCT 和集合がその左側にある ALL 和集合をすべてオーバーライドするように処理されます。DISTINCT 和集合は、UNION DISTINCT を使用して明示的に、あるいはそのあとに DISTINCT または ALL キーワードのない UNION を使用して暗黙的に生成できます。

個々の SELECTORDER BY または LIMIT を適用するには、この句を SELECT を囲む括弧内に配置します。

(SELECT a FROM t1 WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY a LIMIT 10);

ただし、個々の SELECT ステートメントに対して ORDER BY を使用しても、UNION がデフォルトでは、順序付けされていない行のセットを生成するため、最終的な結果に行が現れる順序には何も影響を与えません。そのため、このコンテキストでは通常、ORDER BYLIMIT と組み合わせて使用されます。それにより、選択された行の UNION の最終結果での順序に必ずしも影響を与えるわけではないにもかかわらず、SELECT で取得するためのこれらの行のサブセットを決定するために使用されるようになります。ORDER BYSELECT 内に LIMIT なしで現れた場合、この句はいずれにしても何も効果がないため、最適化によって削除されます。

ORDER BY または LIMIT 句を使用して UNION の結果全体をソートまたは制限するには、個々の SELECT ステートメントを括弧で囲み、最後のステートメントのあとに ORDER BY または LIMIT を配置します。次の例では、この両方の句を使用しています。

(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;

括弧のないステートメントは、今示した括弧で囲まれたステートメントと同等です。

この種の ORDER BY は、テーブル名 (つまり、tbl_name.col_name という形式の名前) を含むカラム参照を使用できません。代わりに、最初の SELECT ステートメント内にカラムのエイリアスを指定し、そのエイリアスを ORDER BY 内で参照します。(あるいは、ORDER BY 内でカラムを、そのカラム位置を使用して参照します。ただし、カラム位置の使用は非推奨です。)

また、ソートされるカラムにエイリアスが指定されている場合、ORDER BY 句はそのカラム名ではなく、エイリアスを参照する必要があります。次のうちの最初のステートメントは機能しますが、2 番目は「カラム 'a' は 'order clause' にはありません」というエラーで失敗します。

(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY b;
(SELECT a AS b FROM t) UNION (SELECT ...) ORDER BY a;

UNION の結果内の行が、各 SELECT によって 1 つずつ取得された行のセットで構成されるようにするには、ソートカラムとして使用する各 SELECT 内の追加のカラムを選択し、最後の SELECT のあとに ORDER BY を追加します。

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col;

さらに個々の SELECT の結果内のソート順序を維持するには、ORDER BY 句にセカンダリカラムを追加します。

(SELECT 1 AS sort_col, col1a, col1b, ... FROM t1)
UNION
(SELECT 2, col2a, col2b, ... FROM t2) ORDER BY sort_col, col1a;

また、追加のカラムを使用すると、各行がどの SELECT から取得されるかを決定することもできます。追加のカラムでは、テーブル名を示す文字列などのほかの識別情報も指定できます。