【メモ】 MySQL5でのUNION内の動作

もの凄い初歩的なことなんですが、
UNIONを使ってクエリを結合するときに関するメモ。
メモるほどのことじゃないかもしれないんですが、
書いて覚えとく、って感じで。


全ての参照元は、マニュアル。

MySQL AB :: MySQL 5.1 リファレンスマニュアル :: 12.2.7.2 UNION 構文


運用は、実は、MySQL5.0.27なんだけど、
5.1マニュアルで大体OKだったので、これで。


まず、基本形は以下。

SELECT a FROM t1 WHERE a=10 AND B=1
UNION
SELECT a FROM t2 WHERE a=11 AND B=2
;

この場合だと、重複する結果は省かれる(DISTINCT)。
もし、重複する結果も全て得たいときには、ALLを付ける。

SELECT a FROM t1 WHERE a=10 AND B=1
UNION ALL
SELECT a FROM t2 WHERE a=11 AND B=2
;


次に、検索結果全体に対してORDER BYを適用するときには、
括弧を使う。

(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も同様。

(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
LIMIT 0, 50
;


UNIONで繋ぐクエリそれぞれに対して、ORDERを使う場合には、
それぞれの括弧の中で指定してやればいいのだけど、注意点として、
どうやら、LIMITと一緒に使わないときちんと動かないっぽい。
(この辺、かなりマニュアルを読み飛ばしてますが…大体そんな感じ)

このクエリなら望んだ結果が返ってきます。

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



あと、最初にはまったのは、
全体へのORDER BY はテーブル名を含むカラム参照を利用する事ができない
ということ。

カラム名が被ってない場合には、それを直接指定してやればいいのだけど、
もし被ってる場合には(例えば、idとかnameとかを共通して使ってる場合には)、
それに対してエイリアスを指定してやって、
ORDER BY 内でそのエイリアスを参照してやれば解決する。

(SELECT a as t1a FROM t1 WHERE a=10 AND B=1 ORDER BY t1.a LIMIT 0, 20)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2 ORDER BY t2.a LIMIT 0, 20)
ORDER BY t1a
;


これを、テーブル名を指定してしまうと、
次のエラーが出てしまう。