【メモ】 MySQL5でのUNION内の動作 【メモ】 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
;



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

 
 
Table 't1' from one of the SELECTs cannot be used in global ORDER clause
 
 
 

やー解決して良かった。


これで大体解決できるけど、
不安なのは、

 
 
個々の SELECT ステートメントへの ORDER BY の利用は、最終結果の中で行がどのような順番で現れるのかを暗示しません
 
 
 

この辺かなぁ。

まぁもしなんかはまったら、マニュアル最後の2つを試すことにしよう。


とりあえず。これで。

COMMENTS