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
;
これを、テーブル名を指定してしまうと、
次のエラーが出てしまう。