UNION と UNION ALL 集合演算子

UNION 集合演算子とは複数の SELECT 文を1つに組み合わせる演算子である。 複数の問い合わせを1つに結合することから、それぞれの問い合わせの抽出項目のリストは同数、かつ、同じグループの データ型 でなければ結合することができない。

簡単な UNION のサンプル

UNION ALL

UNION ALL :2つの問い合わせ結果のレコードが 同じ内容であっても重複行も含める 結果にする。重複データを許す和集合。

SELECT 1, 2 FROM DUAL
UNION ALL
SELECT 1, 2 FROM DUAL;
         1          2
---------- ----------
         1          2
         1          2

UNION

UNION :2つの問い合わせ結果のレコードが 同じ内容であった場合、重複行は削除して 結果にする (≒ SQL の DISTINCT 処理)。重複データのない和集合。

SELECT 1, 2 FROM DUAL
UNION
SELECT 1, 2 FROM DUAL;
         1          2
---------- ----------
         1          2

2つの問い合わせ結果セットに重複データでないことが明確な場合には UNION ALL を使って重複行の削除処理を省く方が実行コストが低い。
重複データの削除にはデータのハッシュ化、ソートなどが必要となる。

UNION できない例

項目数の不一致

SELECT 1, 2 FROM DUAL
UNION ALL
SELECT 1, 2, 3 FROM DUAL;
-- リストの項目数が合わない
行1でエラーが発生しました。:
ORA-01789: 問合せブロックにある結果の列数が正しくありません

データ型の不一致

SELECT 1 FROM DUAL
UNION ALL
SELECT SYSDATE FROM DUAL;
-- 数値と日付を UNION ALL
行1でエラーが発生しました。:
ORA-01790: 式には対応する式と同じデータ型を持つ必要があります

UNION と並び替え(ORDER BY)

UNION を使用した SELECT 文の ORDER BY の構文は

SELECT ... FROM ... [WHERE...] [GROUP BY] [HAVING]
[UNION] の次に [ORDER BY] となる

つまり

SELECT ... FROM ... ORDER BY ...
UNION
SELECT ... FROM ... ORDER BY ...

という SELECT 文はエラーとなる。

UNION した後の並び替え

UNION 結合した後でデータを並び替えるときに困っている場合には項目別名を使用すると良い(※)。 というのも集合演算子を使用するケースではリストの項目名が異なっている場合やファンクションを 使用していることが多い。そのときには項目に別名をつけて、その別名で並び替えを行なう。
(注意) それぞれの問い合わせで異なる別名を付けているだけではエラーにならないが最初の別名だけが有効で 2番目の別名は使用できない。

(※) 列番号を使用しても良いが後々に発生するであろうメンテナンスを考慮すると別名を使用した方が良いだろう。

  • 別名は最初の定義のみが有効
SELECT 'あいう' "ONE", 'さしす' "TWO" FROM DUAL
UNION ALL
SELECT 'いうえ' "ONE_ONE", 'かきく' "TWO_TWO" FROM DUAL
ORDER BY ONE, TWO ;
...
結果省略
  • 後続の別名は無効になる
SELECT 'あいう' "ONE", 'さしす' "TWO" FROM DUAL
UNION ALL
SELECT 'いうえ' "ONE_ONE", 'かきく' "TWO_TWO" FROM DUAL
ORDER BY ONE_ONE, TWO_TWO ;
 
行4でエラーが発生しました。:
ORA-00904: "ONE_ONE": 無効な識別子です。
  • 後続の問い合わせだけに別名を付けても無効になる
SELECT 'あいう' , 'さしす' FROM DUAL
UNION ALL
SELECT 'いうえ' "ONE", 'かきく' "TWO" FROM DUAL
ORDER BY ONE, TWO ;
 
ORA-00904: "ONE": 無効な識別子です。

UNION 内での SELECT の結果セットを並び替えに反映したい場合

SELECT col1, col2 FROM table1   ---(1)
UNION ALL
SELECT col1, col2 FROM table2   ---(2)
ORDER BY  col1, col2

といった SQL 文で (1)の結果をまず優先にして昇順に並び替えたい場合

SELECT 0 "PRE_SORT_KEY", col1, col2 FROM table1
UNION ALL
SELECT 1 "PRE_SORT_KEY", col1, col2 FROM table2
ORDER BY  PRE_SORT_KEY, col1, col2
 


UNION ALL と更新可能なビュー

UNION [ALL] / INTERSECT / MINUS 集合演算を使用したビューは更新できないビューとなる。
ORA-01732: このビューではデータ操作が無効です というエラーになる。

標準SQL では更新が認められるようになっている UNION ALL 集合演算子による結合においても現在のところ(Oracle 10g) 更新できないビューになっている。

SQL - UNION ALL 関連

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ オラクルサポートセンター