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;