SQLで複数の検索結果の和を取るUNIONとUNION ALL、違いが分からずに使っていませんか?

UNIONとUNION ALLには明確な違いがあります。

この違いを理解せずに使ってしまうと、想定外の検索結果になってしまうことになります。

そして、その可能性は複雑なクエリになればなるほど高くなり、修正対応も難しくなってしまいます。

そこで、今回はUNIONとUNION ALLの違いを説明し、動作の違いを見て学んでいただこうと思います。

今回使うデータについて

今回はUNIONとUNION ALLという複数のテーブルの和を取る動作を確認するため、以下の2つのテーブルを用意します。

なお、社員名は架空の組織に所属する人の名前であり、実際に存在する組織の人の名前とは全く無関係です。

①企画部テーブル

②開発部テーブル

この2つのテーブルのSELECT文の結果をUNION、UNION ALLで結合することを考えたいと思います。

UNIONを使ったクエリとクエリの実行結果

UNIONを使ったクエリの例として以下のクエリを実行してみます。

SELECT 社員番号, 社員名, 課番号, 課名
FROM 開発部
UNION
SELECT 社員番号, 社員名, 課番号, 課名
FROM 企画部

このクエリを実行すると以下のようになります。

さて、この実行結果をよく見て頂きたいのですが、企画部テーブルと開発部テーブルの両方に存在していた「0005 田中喜介」、「0008 西澤亮」が1つしか出ていません。

UNIONを使った時は、重複行を消すという動作があるためであり、複数の同じ検索結果が存在する場合でも1つしか検索結果が出てきません

そのため、大きなデータ同士の和を取るためにUNIONを使うと動作が遅くなってしまいます。

つまり、クエリを実行する時の性能面でのボトルネックになりやすいという欠点があります。

そのため、同じ検索結果を削除する必要が本当にあるのかをよく考えてUNIONを使う必要があります。

UNION ALLを使ったクエリとクエリの動作結果

では、今度はUNION ALLを使った時の例として以下のクエリを考えてみます。

SELECT 社員番号, 社員名, 課番号, 課名
FROM 開発部
UNION ALL
SELECT 社員番号, 社員名, 課番号, 課名
FROM 企画部

このクエリを実行すると、以下のようになります。

この実行結果を見ると、単純に2つのSELECT文の結果を結合しただけで、「0005 田中喜介」、「0008 西澤亮」も重複して出現しています。

UNION ALLを使うと、ただ複数のSELECT結果を結合するだけであり、大量のデータの和を取る場合に、UNIONよりも高速で実行することが可能です。

ただし、この動作について気を付けたいことがあります。

それは、UNION ALLの結果をSELECTでデータを抽出する場合です。

この時に1行のみを取得することを想定していると、複数行取得できる場合もあるため、このことを考慮したプログラムを書かないとプログラムに不具合が生じることになります。

つまり、重複行に関して考慮しないとUNION ALLを使った場合は、1行のみのデータ取得を想定したプログラムにするのは良くないということです。

UNION ALLを使ったサブクエリに対し、DISTINCTを使うか、複数行を取得することを考慮したプログラミングを行うかのどちらかの対応を行う必要があることを覚えておかなければなりません。

この考慮が漏れていると想定外の動作が起き、プログラムがエラーで止まってしまうことがありますので、きちんと考慮漏れが無いようにする必要があります。

まとめ

今回はSQLのUNIONとUNION ALLの動作の違いを説明しました。

知っておいて欲しいのは以下の通りです。

  1. UNIONは重複行を削除するが、UNION ALLは重複行を許す
  2. UNIONは重複行をチェックするため動作が遅いが、UNION ALLは単純にSELECT結果を結合するだけなので動作が早い
  3. UNION ALLを使用する際は、プログラム側やクエリで重複行を取得する動作を考慮する必要がある

UNIONとUNION ALLは複数の検索結果の和を取得できる便利なものですが、きちんと違いを理解していないと良いプログラムを書くことが出来ません。

盲目的にUNIONを使うと性能試験で引っかかりますし、UNION ALLを盲目的に使うと複数行を取得することがあるため、単一行の取得を前提とした処理を組んだ時にエラーで落ちる可能性があります。

そのため、UNIONとUNION ALLはきちんと違いを理解して使うことを意識しておかなければ、優れたプログラムは書けません。

UNIONとUNION ALLの挙動の違いは、クエリを書く場合も、クエリを使用するプログラムを書く場合もしっかりと理解しておきたいところであります。

今回の記事はここまでとなります。
また次の記事でお会いしましょう。