[SQL, Oracle] テーブルの合体 - UNION & UNION ALL

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 Xselect \* from Y
1111
222null
3null3null
nullnullnullnull
select \* from X union all select \* from Y
11
22
3null
nullnull
nullnull
11
2null
3null

4件 + 4件 = 8件になる。単純な足し算。

UNION

  • UNION ALLと違い重複したデータはまとめる
  • UNION ALLと違いソートされる
select \* from Xselect \* from Y
1111
222null
3null3null
nullnullnullnull
select \* from X union all select \* from Y
11
11
22
2null
3null
3null
nullnull

(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: 式には対応する式と同じデータ型を持つ必要があります
Share