UNION または UNION ALL はカラムが同じ構成の2つのテーブルを合体する。結合ではない。
概略
- テーブルを割りと単純にマージする
- マージするときのカラム名の違いは考慮されない
- マージする時に考慮するのは select で取り出すカラムの数と型と順番
- 型のサイズは大きい方に合わせられるので違っても良い
以下のデータを利用してテストする
create table X ( X1 char(1), X2 number(1,0) );
create table Y ( Y1 char(2), Y2 number(9,0) );
insert into X values( 1, 1);
insert into Y values( 1, 1);
insert into X values( 2, 2);
insert into Y values( 2, null);
insert into X values( 3, null);
insert into Y values( 3, null);
insert into X values(null, null);
insert into Y values(null, null);
UNION ALL
- [重要] UNIONと違い重複したデータはまとめないし、ソートもしない。 なのでUNIONよりも高速なことが多い。
- UNIONより名前が長いから複雑そうな印象を受けたけど、こっちのほうが単純でテーブルをくっつけるだけ
- カラム名は元テーブルの名前が利用される
select \* from X | select \* from Y | ||
1 | 1 | 1 | 1 |
2 | 2 | 2 | null |
3 | null | 3 | null |
null | null | null | null |
select \* from X union all select \* from Y | |
1 | 1 |
2 | 2 |
3 | null |
null | null |
null | null |
1 | 1 |
2 | null |
3 | null |
4件 + 4件 = 8件になる。単純な足し算。
UNION
- UNION ALLと違い重複したデータはまとめる
- UNION ALLと違いソートされる
select \* from X | select \* from Y | ||
1 | 1 | 1 | 1 |
2 | 2 | 2 | null |
3 | null | 3 | null |
null | null | null | null |
select \* from X union all select \* from Y | |
1 | 1 |
1 | 1 |
2 | 2 |
2 | null |
3 | null |
3 | null |
null | null |
(null, null) の行はまとめられて1つになり、計7件。
(1, 1)の行や(3, null)の行がまとめられないのは charchar(2)のデータは半角スペース含みの "1 " なので違う文字列だから。
char のサイズ違いなどでまとまらない場合があるので注意。 下のようにするとまとまる。
set null null;
select * from X union select rtrim(Y1), Y2 from Y;
X1 X2
---- ----------
1 1
2 2
2 null
3 null
null null
今度はきちんとまとめられて5件になる。
UNION と UNION ALL が実行不能な条件
型が違ってる
create table X ( ID char(1) );
create table Y ( ID number(1, 0) );
select * from X union select * from Y;
-- ORA-01790: 式には対応する式と同じデータ型を持つ必要があります
列の数が違う
create table X ( ID char(1) );
create table Y ( ID char(1), TAG char(1) );
select * from X union select * from Y;
-- ORA-01789: 問合せブロックにある結果の列数が正しくありません
下のように数を合わせればOK
select * from X union select TAG from Y;
順番が違っている
勝手に並べ替えたりはしない親切仕様
create table X ( A char(1), B number(1,0) )
create table Y ( B number(1,0), A char(1) );
select * from X union select * from Y;
-- ORA-01790: 式には対応する式と同じデータ型を持つ必要があります