MySQL 5.1 リファレンスマニュアル :: 12 SQL ステートメント構文 :: 12.2 データ取り扱いステートメント :: 12.2.7 SELECT 構文 :: 12.2.7.2 UNION 構文
« 12.2.7.1 JOIN 構文

12.2.8 サブクエリ構文 »
Section Navigation      [Toggle]
  • 12.2.7 SELECT 構文
  • 12.2.7.1 JOIN 構文
  • 12.2.7.2 UNION 構文

12.2.7.2. UNION 構文

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

UNION は、結果を複数 SELECT ステートメントから単一結果セットに結合させる為に利用されます。

最初の SELECT ステートメントからのカラム名は、返された結果のカラム名として利用されます。各 SELECT ステートメントの対応する位置にリストされている選択されたカラムは、同じデータ タイプを持つ必要があります。(例えば、最初のステートメントに選択された最初のカラムは、別のステートメントに選択された最初のカラムと同じタイプを持つ必要があります。)

もし、対応する SELECT カラムのデータ タイプが一致しなければ、UNION 結果内のタイプとカラムの長さは、全ての SELECT ステートメントによって検索された値を考慮する必要があります。例えば、次の物を検討してみてください。

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

(MySQL の初期のバージョンでは、最初の SELECT のタイプと長さだけが利用され、2つ目の行は長さ1まで切り捨てられていました。)

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

  • 最後の SELECT ステートメントだけが INTO OUTFILE を利用できます。

  • HIGH_PRIORITY は、UNION の一部である SELECT ステートメントと一緒には利用できません。

    もしそれを最初の SELECT に指定しても、効果はありません。もしそれを後に続く SELECT ステートメントに指定すると、構文エラーが起こります。

UNION のデフォルトの動作は、複製行は結果から削除されるという事です。任意の DISTINCT キーワードは、複製行の削除の指定もするので、デフォルト以外に何も効果は持ちません。任意の ALL キーワードを利用すると、複製行の削除は行われず、結果には全ての SELECT ステートメントからの一致する行が含まれます。

UNION ALL と UNION DISTINCT を同じクエリの中で混合する事ができます。混合された UNION タイプは DISTINCT ユニオンが全ての ALL ユニオンをその左側に上乗せするような形で扱われます。DISTINCT ユニオンは UNION DISTINCT を利用して明示的に、また後に DISTINCT や ALL キーワードがない UNION を利用して暗黙的に作成されます。

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 条項は、カラム名ではなく、そのエイリアスを参照 しなければいけません。次のステートメントの1つ目の物は機能しますが、2つ目は Unknown column 'a' in 'order clause' エラーで失敗します。

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

個々の SELECT に ORDER 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);

デフォルトの UNION が不規則な順番の行セットを作り出す為、個々の SELECT ステートメントへの ORDER BY の利用は、最終結果の中で行がどのような順番で現れるのかを暗示しません。もし ORDER BY が LIMIT と共に現れると、検索の為に選択された行のサブセットを SELECT に決定する為に利用されますが、それは最終的な UNION の結果内の行の順番に影響を与えるとは限りません。もし ORDER BY が SELECT 内に LIMIT 無しで現れても、何の効果も持たない為最適化されて切り離されます。

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;
Copyright © 1997, 2010, Oracle and/or its affiliates. All rights reserved. Legal Notices
Top / Previous / Next / Up / Table of Contents
© 2010, Oracle Corporation and/or its affiliates