SQL Everyone学習する
SQL EveryoneSQL Everyone
  • トップ
  • マイページ
  • データベース確認
  • 学習ページ
    • SQL概要
    • SQL実行環境構築
    • SQL文法基礎
    • SQL実践問題(初級)
    • SQL実践問題(中級)
    • SQL実践問題(上級)
SQL EveryoneSQL Everyone
  • トップ
  • マイページ
  • データベース確認
  • 学習ページ
    • SQL概要
    • SQL実行環境構築
    • SQL文法基礎
    • SQL実践問題(初級)
    • SQL実践問題(中級)
    • SQL実践問題(上級)
料金プランお問い合わせセミナー記事
プライバシーポリシー利用規約特定商取引法表記

© 2026 SQL Everyone

読み込み中...
SQL文法基礎5/8
No.5

【SQL文法基礎5】複数のテーブルを「縦」に結合する 〜 UNION 〜

前章では、テーブルを横に結合する方法としてJOINについて学びました。 本章ではもう1つ、テーブルを縦に結合する方法を学びます。結合方法に関して、ぜひJOINとの違いも合わせて学んでいきましょう。

複数のテーブルを「縦に」結合するUNION

JOINとUNIONの違い

2つ以上のテーブルを結合して、データを取得するときに使われるのがJOINですが、JOIN以外にもテーブルを結合する方法があります。JOINの場合はテーブルを横に結合する方法として、新しくカラムが追加されるようなイメージでテーブルを結合します。

もう1つ、テーブルを縦に結合して、テーブルの行を追加する方法があります。それがUNIONを使った結合方法です。JOINの場合はテーブルを横に結合するため、共通のカラムを指定する必要がありました。UNIONの場合はテーブルを縦に結合するため、結合するテーブルのカラム情報が一致している必要があります。

・図7-1:JOINとUNIONの違い

例えば、図7-2のように顧客情報テーブルが2つあった場合を考えてみましょう。顧客情報テーブル①には顧客ID(user_id)と年齢(age)の2つのカラムがあり、顧客情報テーブル②には顧客ID(user_id)と性別(gender)の2つのカラムがあります。この場合、UNIONを使ってテーブルを縦に結合することはできません。なぜなら、顧客ID(user_id)という共通のカラムはありますが、性別(gender)と年齢(age)という別々のカラムが存在するため、テーブルを縦に結合しようとすると、整合性が取れずに結合することができないからです。

・図7-2:テーブルを縦に結合できない場合

次に、図7-3のような顧客情報テーブルが2つあった場合を考えてみましょう。顧客情報テーブル①と顧客情報テーブル②はどちらも顧客ID(user_id)と年齢(age)の共通する2つのカラムがあります。つまり、図7-3の場合は2つある顧客情報テーブルのカラム情報が一致しているため、UNIONを使ってテーブルを縦に結合することができます。

・図7-3:テーブルを縦に結合できる場合

このように、テーブルを縦に結合する場合は、テーブルのカラム情報が一致している必要があります。図7-2のようにカラムが一致していない場合は、顧客ID(user_id)のような共通のカラムが存在すれば、JOINを使ってテーブルを横に結合することはできるかもしれません。テーブルを縦に結合する場合はUNIONを使い、テーブルを横に結合する場合はJOINを使うなど、それぞれのテーブルに合わせて使い分けができるようにしましょう。

UNIONの基本構文と種類

ここからは、SQLでUNIONを使うときの基本構文について解説します。UNIONは2つのテーブルを縦に結合することができるため、SELECTで取得した2つのテーブルの出力結果をUNIONを使って結合することができます。

・UNIONの基本構文

</>
1
2
3
4
5
SELECT * FROM テーブル1

UNION

SELECT * FROM テーブル2

また、UNIONにはUNIONとUNION ALLの2種類が存在します。UNIONはデータを結合するときに重複する行があったら重複行を削除して結合します。一方のUNION ALLは、重複する行があっても重複行は削除せずに結合します。

結合方法

意味

UNION

データに重複があった場合に重複行を排除して結合する

UNION ALL

データに重複があった場合に重複行を排除せずに結合する

重複する行とはすべてのカラムのデータが一致していることを指します。例えば、顧客IDと年齢が入った2つの顧客情報テーブルが存在した場合を考えてみます。図7-4のように、それぞれのテーブルに顧客ID(user_id)と年齢(age)がまったく同じ行で存在したとします。このとき、UNIONを使って2つのテーブルを結合すると、重複した行は1行だけが出力されます。

一方で、UNION ALLを使って結合すると、重複を排除せずに結合されるため、重複した行でも2行出力されます。データ分析ではどちらもよく活用されるので、重複を排除したほうがよいのか、重複は排除しないほうがよいのか、集計したいデータの内容に合わせて使い分けることが重要です。

・図7-4:UNIONとUNION ALLの違い

データ分析でよく使うUNIONのパターン

データの前処理としての結合

データ分析は、前処理に時間がかかるといわれています。前処理とは、SQLを使ってデータを集計する前に、テーブルの情報を整えたり、データを1つにまとめたりする作業のことです。例えば、顧客情報を管理するテーブルがあったときに、サービスのリニューアルやデータベースの再設計など、なんらかの理由で顧客情報テーブルが複数のテーブルに分かれてしまうことがあります。また、データの量が多いと、日付などでテーブルを分割してデータを保存することもあります。

データの管理という観点では、データを分割したほうが効率がよい場合もあるので、構造が同じデータが複数のテーブルに保存されることもあります。しかし、複数のテーブルにデータが保存されていると、データを取得するときにそのつどどのテーブルからデータを取得するのか選択する必要があるため、データ分析の観点では非効率になる場合があります。

・図7-5:テーブルが複数ある場合

構造が同じデータが複数のテーブルに保存されている場合、前処理としてUNIONを使って1つのテーブルにまとめることができます。複数のテーブルをUNIONを使ってまとめることで、1つのテーブルからデータを取得できます。

・図7-6:テーブルを1つにまとめた場合

このように、複数のテーブルを1つのテーブルにまとめることで、効率的にデータ分析ができるようになります。JOINのときにも解説したとおり、データ分析ではほしいデータがあらかじめ1つのテーブルにまとまっているとは限りません。同じ構造でテーブルが複数に分かれているときは、UNIONを使ったテーブルの結合が非常に便利です。

集計結果を縦にまとめて求めたい場合

UNIONを使うことで、テーブルを縦に結合することができます。その特徴を活かして、集計結果が横で得られたものを縦にして求めたい場合に、UNIONを活用できます。例えば、顧客情報テーブルから誕生年の最大値と最小値を求めたい場合を考えてみましょう。

まずは復習として、SQL7-1を実行し、出力結果を確認してみましょう。SQL7-1は、顧客情報テーブル(users)から誕生年(birth_date)の最大値(MAX)と最小値(MIN)を求めています。これはSELECTのあとにMAX(EXTRACT(YEAR FROM birth_date))とMIN(EXTRACT(YEAR FROM birth_date))という2つの集計結果を指定しているため、誕生年の最大値と最小値の2つのデータが横に出力された状態になります。

★ハンズオン〜SQLを実行してみよう〜

・SQL7-1

</>
1
2
3
4
5
SELECT
    MAX(EXTRACT(YEAR FROM birth_date)) AS max_birth,
    MIN(EXTRACT(YEAR FROM birth_date)) AS min_birth
FROM
    users

・表7-7:SQL7-1の実行結果

max_birth

min_birth

2003

1941

もちろん、単純にデータを集計したい場合は、これでもまったく問題ありません。しかし、集計結果を横に出力するのではなく縦に出力したい場合、UNION(UNION ALL)を活用することができます。

データを横持ちから縦持ちに変更したことを確認するために、SQL7-2を実行して出力結果を確認してみましょう。SQL7-1では、結果を横にまとめて出力しましたが、SQL7-2ではUNION ALLを使って結果を縦にまとめています。

まず、SQL7-2の1つ目のSELECT文では、顧客情報テーブルからMAX(EXTRACT(YEAR FROM birth_date))で誕生年の最大値を取得しています。2つ目のSELECT文では、MIN(EXTRACT(YEAR FROM birth_date))で誕生年の最小値を取得しています。それら2つの出力結果をUNION ALLを使って結合しているのがSQL7-2です。

SQL7-2では、UNION ALLを使っていますが、今回の場合は、重複する行は存在しないので、UNIONでもUNION ALLでもどちらを使っても同じ結果になります。また、結合するときにどちらが誕生年の最大値と最小値なのか出力結果テーブル上でもわかるように、誕生年の最大値をmax_birth、最小値をmin_birthという文字列にして、ASを使ってカラム名をdata_keyと設定しています。UNION ALLを使ってテーブルを結合するときは、両方のテーブルのカラムが同じでないと結合ができないので、どちらも同じdata_keyとdata_valueという2つのカラムが出力されるようにしています。

★ハンズオン〜SQLを実行してみよう〜

・SQL7-2

</>
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT
    'max_birth' AS data_key,
    MAX(EXTRACT(YEAR FROM birth_date)) AS data_value
FROM
    users
 
UNION ALL

SELECT
    'min_birth' AS data_key,
    MIN(EXTRACT(YEAR FROM birth_date)) AS data_value
FROM
    users

・表7-8:SQL7-2の実行結果

data_key

data_value

max_birth

2003

min_birth

1941

今回のように、誕生年の最大値と最小値を求めるくらいであれば、UNION ALLを使わないほうがシンプルにデータを取得できます。しかし、出力結果を横持ちではなく縦持ちで結果がほしい場合は、UNION(UNION ALL)を使うことで縦持ちに変換できます。

データ分析における「UNION」の考え方

複数のテーブルを結合する方法として、テーブルを横に結合するJOINと、テーブルを縦に結合するUNIONがあります。どちらもテーブルの結合という意味では同じですが、結合の仕方がそれぞれ違うので、どのようなデータを取得するのかに応じて使い分ける必要があります。図7-9のように、複数のテーブルを「縦」に結合して出力結果を求めることがUNIONで重要な考え方です。つまり、UNIONは、テーブルの行を追加する結合方法であると覚えておきましょう。

・図7-9:UNIONの考え方

演習問題

演習問題7-1

商品情報テーブル(products)から商品の価格の最大値と最小値と平均値を出力してください。結果はUNION(UNION ALL)を使って、出力結果が縦になるようにしてください。

演習問題7-2

購入履歴テーブル(orders)から2023年1月1日から2023年1月31日までの購入件数と、2023年12月1日から2023年12月31日までの購入件数を出力してください。条件として、キャンセルのある購入データは除外してください。結果はUNION(UNION ALL)を使って、出力結果が縦になるようにしてください。

前のレッスン

複数のテーブルを「横」に結合する〜 JOIN 〜

次のレッスン

条件に合わせて分類をする〜 CASE 〜