SQLの結果表示に便利なunionの使い方を覚えよう
unionの使い方と注意点をサンプルのデータとSQLを使ってご紹介します。
unionの使い方と注意点をサンプルのデータとSQLを使ってご紹介します。
スキルアップ
2022/12/26 UP
- プログラミング
- インフラエンジニア
- 開発
複数のselect文を結合して表示するのがunionです。データ抽出時、いくつもselect文を発行して、抽出結果を後から表計算ソフト等で結合するような作業をしている方がいらっしゃれば、その手間が省けます。unionを使えば1本select文を発行するだけで、結合後の結果を取得できるのが特徴です。
便利なunionですが結合する結果の項目数を合わせるなど使う際には注意点もあります。
unionの使い方と注意点をサンプルのデータとSQLを使ってご紹介します。
unionとunion allの使い方を知る
unionと、unionとよく比較されるunion allの使い方を説明します。
unionの概要
select文の結果を結合するのがunionですが、結合する結果は2つ以上でも構いません。結合するselect文が増えるほどレコード数が増えるため、抽出時の負荷には気をつけたいですが、3つや4つのselect文を結合できます。抽出結果の列数が一致していれば結合できるので、元のテーブルの列数は問いません。
年度違いの売上データを3年分まとめて表示させるなど、同じ構造を持ったデータをまとめて見るときなどはunionで結合すると便利です。
unionとunion allの違い
unionと同時に覚えておきたいのがunion allです。複数のselect文の抽出結果を結合して表示することは同じですが、union allは重複を含むすべてを抽出します。
重複を認めるため、表示するレコード数はunion allの方が多くなります。重複を認めないunionは重複排除をする分だけ、抽出処理に時間がかかります。特別指定や意図がないときはunion allを使います。レコードの内容次第にはなりますが、union allで抽出した後、抽出結果を編集して重複排除する方がスムーズに作業できます。
unionの使い方
unionの使い方を、サンプルデータを使ってご紹介します。
unionを使ったSQLの書き方
総務担当のメンバーの情報が入った総務テーブル、経理担当のメンバーの情報が入った経理テーブルを結合し、総務と経理に所属するメンバーを1つの抽出結果で確認しましょう。
総務テーブルには以下のデータが格納されています。
社員番号 | 氏名 |
---|---|
4040224 | 田中重郎 |
4090784 | 山田和美 |
経理テーブルには以下のデータが格納されています。
社員番号 | 氏名 |
---|---|
4040224 | 田中重郎 |
5020193 | 鈴木剛規 |
どちらのテーブルにも田中重郎のレコードがあり、田中重郎は総務と経理の兼務になっています。
これらのテーブルからunionを使ってデータを抽出します。
select * from 総務 union select * from 経理
社員番号と氏名の両方を出力したいケースであるため、表示する列は指定せず、すべての列を表示する「*」を使います。
select 社員番号,氏名 from 総務 union select 社員番号,氏名 from 経理
この書き方をして、出力する列を明示で指定しても同じ結果が得られます。テーブルに抽出したいデータ以外の列が含まれているときや、SQLを見ただけで何の列を表示しているか明確にしたいときはこの書き方が便利です。ただし列名が誤っているとSQLはエラーになるため、たくさんの列を指定する場合は気をつけましょう。
このSQLの結果は以下の通りです。
社員番号 | 氏名 |
---|---|
4040224 | 田中重郎 |
4090784 | 山田和美 |
5020193 | 鈴木剛規 |
unionは重複を排除するため、3レコードが表示されます。
union allを使う場合、このようになります。
select * from 総務 union all select * from 経理
結果は以下の通りです。
社員番号 | 氏名 |
---|---|
4040224 | 田中重郎 |
4090784 | 山田和美 |
4040224 | 田中重郎 |
5020193 | 鈴木剛規 |
union allは重複を排除しないため、4レコードが表示されます。田中重郎は2レコード表示されています。
なおSQLで明示的に表示順を並べ替えない限り、出力するたびにレコードの順番が変わる可能性があるので注意しましょう。union allで重複を含めてデータを抽出し、抽出後のデータで重複を削除するような編集をするときは、あらかじめ抽出結果を並べ替え、重複データが上下に並ぶようにしておく方が便利です。
union、union allどちらを使う場合にも結合するテーブルに入っているデータ量は気にしておきましょう。抽出件数に上限を設けたり、条件指定を行ったりしない限り、全レコードを結合してしまうのがunion、union allです。データ量が増えると負荷の高い抽出になりかねません。必要な列だけに絞るなど欲しい分だけ結合結果を得る工夫をしておくと抽出も速くなります。
unionを使う際の注意点
unionを使う際の注意点をご紹介します。なおunion allも同じルールを持っているため、注意点はunion allでも同じポイントになります。
結合する項目数は合わせる
unionを使うにはselect文で表示する列の数を合わせ、結合する項目数を合わせなければなりません。元のテーブルの項目が一致している必要はなく、select文で抽出した結果の列数が一致していれば問題ありません。
一致していないときはSQLエラーとなり結果が出力されません。unionを実行してエラーが出てしまった場合は、結合しているselect文の列数を確認してみましょう。
データ型を合わせる
結合する列のデータの型は合わせなければなりません。片方が文字型、片方が数値型などデータ型が異なる場合はunionを使えません。指定する列すべてが対象となるため、左から順番に指定する順番も間違えないようにしましょう。
DBMSによっては暗黙でデータ型を変換してくれるため、SQLエラーにならないものもあります。SQLで結果を表示するだけならまだしも、プログラムのなかで抽出結果を使おうとすると、データ型がわからなくなる原因の一つになります。
原則はデータ型の一致は必要であると覚えておくのが安全です。
組み合わせて使うと便利なデータ操作言語
union、union allと合わせて使われることが多いデータ操作言語を記載します。
並べ替えるorder by句
抽出結果を並べ替えて表示するのがorder by句です。数字の番号順はもちろん、アルファベット順、五十音順などに並べて表示させることができます。複数の列に順序を設定できるため、アルファベット順に並べた後、サイズ順に並べるといった並べ替えも可能です。
order by句のみを記載したとき、データは昇順で並びます。明示で昇順にしたい場合はASCを追加しましょう。order by ID ASCのように、列名の後に記載します。降順で並べたいときはDESCを記載しましょう。
なおorder by句を書くのは最後に一度だけです。それぞれ並べ替えたテーブルを結合したい場合は、select文をカッコで囲むなど、書き方に工夫が必要になります。慣れるまではorder by句は最後だけに記載すると覚えておきましょう。
絞り込むwhere句にもコツがいる
where句はorder by句とは異なり、結合するselect文のそれぞれに記載します。結合したいデータを絞り込んでからunionでつなぐイメージです。
最後にwhere句を記載してしまうと、select文は一部のテーブルにしか意味をなさなくなるので注意が必要になります。
たとえば先のサンプルデータと同じ総務テーブル、経理テーブルから社員番号が404で始まる社員のデータだけを抽出しようとして、以下のSQLを書いたとします。
select 社員番号,氏名 from 総務 union select 社員番号,氏名 from 経理 where 社員番号 like '404%'
where句は経理テーブルにしか適用されないため、出力結果はこうなります
社員番号 | 氏名 |
---|---|
4040224 | 田中重郎 |
4090784 | 山田和美 |
経理テーブルにはwhere句が適用されますが、総務テーブルにはwhere句が適用されないため、山田和美のデータも出てきてしまいます。
なおunionのため、田中重郎のレコードは重複排除されて1レコードのみ表示されている状態です。
SQLのunionを活用して効率アップを
unionを知っていると何本もselect文を発行する必要がなく、一度でまとめて抽出結果が得られます。データ抽出後、手作業でselect文の結果を結合していた方がいる場合、その作業は丸ごとなくなります。
テーブルを結合するほどレコード件数が増え、抽出の処理負荷が高くなるため、結果表示されるレコード数には注意しておきましょう。
他にもこの記事で挙げた注意点はunionを使う際によく引っかかるポイントです。SQLエラーが出たときはあらためてSQLを見直し、unionを使っていきましょう。