SQL入門
複数のSELECT結果を統合(UNION,UNION ALL)

SQLの初心者向け入門解説、VBAからデータベースを扱うためのSQLを解説
公開日:2019-12-05 最終更新日:2021-04-28

複数のSELECT結果を統合(UNION,UNION ALL)


エクセルVBAでデータベースを扱うためのSQL入門です。
前回のJOINでは複数のテーブルを横に結合するものでしたが、SQLではデータを縦に連結することもできます。


SQLのSELECTした結果は1つのテーブルと同様に見ることができます。
SELECTに書かれているカラムリスト、このカラムを持った新しいテーブルとして扱えます。
SELECTを複数書いて複数の新しいテーブルを作成し、それを縦に連結/統合するイメージになります。
これを行うには、集合演算子(UNION等)を使います。

使用するテーブル定義は以下になります。

全テーブル定義とテーブル自動作成VBA
・テーブル:m_customer ・テーブル:m_item ・テーブル:t_sales ・テーブル自動作成

集合演算:データの統合方法

2つの集合の集合演算には、何通りかあります。
和集合:UNION
差集合:EXCEPT
積集合:INTERSECT
UINION以外は、サポートされていないDBも多くあります。
SQLで最も頻繁に使われ、かつ、ほとんどのDBで共通にサポートされている和集合(UNION)についてのみ詳細に解説します。

差集合は必要となる場合は少ないでしょう。
積集合はINNER JOINでほとんどの場合代替え可能です。
また、EXCEPT、INTERSECTともに、使い方はUNIONと同様で文法的にはUNIONを書き換えれば使えます。

2つのデータを和集合として1つのデータにする場合、SQLでは2通りあります。

VBA マクロ SQL UNION 集合演算

和集合:UNION
2つのデータの和集合になります。
重複しているデータは排除されます。

VBA マクロ SQL UNION 集合演算

全体集合:UNION ALL
ALLを指定することで、重複しているデータは排除されず、全体集合になります。

VBA マクロ SQL UNION 集合演算

SQLの集合演算について

UNION等の集合演算は、SELECT文とSELECT文とつなげることができます。
それぞれのSELECTを1つの集合として、集合演算した結果が返されます。

集合演算の結果に対して、さらに次のSELECT文を集合演算することもできます。
つまり、3つ以上のSELECT文の集合演算が可能という事です。

UNION等の集合演算の注意点
注意点として、それぞれのSELECT文の選択リスト(カラム名や式)の列数およびデータ型は一致させる必要があります。
列数やデータ型が違う場合はエラーとなります。
SELECTにより、選択する列数が過不足がある場合、不足している列にはNULLや定数値を指定し列数を合わせてください。

UNION等の集合演算の結果をソート(ORDER BY)
全ての結果をソート(ORDER BY)する場合は、必ず最後のSELECTに記述します。
ソートは、UNION等の集合演算の全ての結果に対して行われます。
しかし、そもそも、それぞれのSELECTの列名がバラバラの場合は、ORDER BYの列名は・・・
少なくともSQLiteでは、どのSELECT文の列名でも動作するようですが、このような使い方は避けるべきでしょう。
それぞれのSELECTの列名が違う場合は、エイリアスで統一した名称にしておくことをお勧めします。
ORDER BYに列名ではなく、選択列番号を指定する方法がサポートされているますが、これは使用するべきではないでしょう。

UNION(和集合)の構文

SELECT文 UNION [ALL] SELECT文

[ALL]を省略すれば和集合、ALLを指定すれば全体集合になります。

EXCEPT(差集合)とINTERSECT(積集合)
SELECT文 EXCEPT [ALL] SELECT文
SELECT文 INTERSECT [ALL] SELECT文

SQLiteでは、ALLが指定できないようです。
EXCEPTもINTERSECTもサポートしていないDBもあります。
もし使用する場合はDBごとに良く確認してください。

差集合は必要となる場合は少ないでしょう。
積集合はINNER JOINでほとんどの場合代替え可能です。

和集合:UNION

以下のクラスを使用して、UNIONを使ったSQLを発行するVBAサンプルです。
VBAクラスの全コード:データの取得
SQL入門の「データの取得:条件指定(SELECT,WHERE)」時点のVBAクラスの全コードです。ADOを使ったDB接続のVBAクラスの全コード クラスモジュール:clsSQLite
Sub SelectUnion()
  Dim clsDB As New clsSQLite
  clsDB.DataBase = "D:\SQLite3\sample.db"
 
  Dim ws As Worksheet
  Set ws = ActiveSheet
 
  Dim sSql As String
  sSql = ""
  sSql = sSql & "SELECT code,item_code"
  sSql = sSql & " FROM t_sales"
  sSql = sSql & " WHERE code = '001'"
  sSql = sSql & "  AND sales_date = '2019-11-01'"
  sSql = sSql & " UNION "
  sSql = sSql & "SELECT code,item_code"
  sSql = sSql & " FROM t_sales"
  sSql = sSql & " WHERE item_code = '10001'"
  sSql = sSql & "  AND sales_date = '2019-11-01'"
  sSql = sSql & " ORDER BY code,item_code"
 
  If Not clsDB.SheetFromRecordset(sSql, ws.Range("A1"), Clear, True) Then
    MsgBox clsDB.ErrMsg
    Exit Sub
  End If
 
  Set clsDB = Nothing
End Sub

重複データはまとめられ(排除され)ます。

VBA マクロ SQL UNION 集合演算

少なくとも、
code = '001'かつ item_code = '10001'
このデータは、どちらのSELECTでも対象となりますが、出力は1件となっています。

全ての列のデータが一致している場合に重複データとみなされます。
1列でもデータが違う場合は別のデータと判定されます。

全体集合:UNION ALL

Sub SelectUnionAll()
  Dim clsDB As New clsSQLite
  clsDB.DataBase = "D:\SQLite3\sample.db"
 
  Dim ws As Worksheet
  Set ws = ActiveSheet
 
  Dim sSql As String
  sSql = ""
  sSql = sSql & "SELECT code,item_code"
  sSql = sSql & " FROM t_sales"
  sSql = sSql & " WHERE code = '001'"
  sSql = sSql & "  AND sales_date = '2019-11-01'"
  sSql = sSql & " UNION ALL "
  sSql = sSql & "SELECT code,item_code"
  sSql = sSql & " FROM t_sales"
  sSql = sSql & " WHERE item_code = '10001'"
  sSql = sSql & "  AND sales_date = '2019-11-01'"
  sSql = sSql & " ORDER BY code,item_code"
 
  If Not clsDB.SheetFromRecordset(sSql, ws.Range("A1"), Clear, True) Then
    MsgBox clsDB.ErrMsg
    Exit Sub
  End If
 
  Set clsDB = Nothing
End Sub

重複データも全て出力されます。

VBA マクロ SQL UNION 集合演算

データが重複して出力されていることが確認できます。

複数のSELECT結果を統合の最後に

今回は、和集合UNIONについて解説しました。
簡単な例題ではUNIONの有用性はなかなか感じられないかもしれませんが、
データベースからSQLでデータ抽出しているといずれ必ず必要になってくるものです。
UNIONの注意点と、ALLの有無による違いはしっかりと把握しておいてください。

次回からは、いったんSELECTから離れて、データベースの更新および削除について解説しておきます。
その後は、SELECTのより高度な使い方についての説明に進みます。



同じテーマ「SQL入門」の記事

データベースの正規化とマスタの作成
全テーブル定義とテーブル自動作成VBA
テーブルを結合して取得(INNER JOIN,OUTER JOIN)
複数のSELECT結果を統合(UNION,UNION ALL)
データの更新(UPDATE)
データの削除(DELETE)
他のテーブルのデータで追加/更新/削除
インデックスを作成して高速化(CREATE INDEX)
トランザクション処理
VBAクラスの全コード:トランザクション処理
サブクエリ(副問合せ)


新着記事NEW ・・・新着記事一覧を見る

カンマ区切りデータの行展開|エクセル練習問題(2026-01-28)
開いている「Excel/Word/PowerPoint」ファイルのパスを調べる方法|エクセル雑感(2026-01-27)
IMPORTCSV関数(CSVファイルのインポート)|エクセル入門(2026-01-19)
IMPORTTEXT関数(テキストファイルのインポート)|エクセル入門(2026-01-19)
料金表(マトリックス)から金額で商品を特定する|エクセル練習問題(2026-01-14)
「緩衝材」としてのVBAとRPA|その終焉とAIの台頭|エクセル雑感(2026-01-13)
シンギュラリティ前夜:AIは機械語へ回帰するのか|生成AI活用研究(2026-01-08)
電卓とプログラムと私|エクセル雑感(2025-12-30)
VLOOKUP/XLOOKUPが異常なほど遅くなる危険なアンチパターン|エクセル関数応用(2025-12-25)
2段階の入力規則リスト作成:最新関数対応|エクセル関数応用(2025-12-24)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.日本の祝日一覧|Excelリファレンス
3.変数宣言のDimとデータ型|VBA入門
4.FILTER関数(範囲をフィルター処理)|エクセル入門
5.RangeとCellsの使い方|VBA入門
6.繰り返し処理(For Next)|VBA入門
7.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
8.マクロとは?VBAとは?VBAでできること|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.メッセージボックス(MsgBox関数)|VBA入門




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。
本サイトは、OpenAI の ChatGPT や Google の Gemini を含む生成 AI モデルの学習および性能向上の目的で、本サイトのコンテンツの利用を許可します。
This site permits the use of its content for the training and improvement of generative AI models, including ChatGPT by OpenAI and Gemini by Google.



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ