【SQL】2つのテーブルのデータを比較して差分を検証する

sql-minus-union
  • URLをコピーしました!

とあるデータベースのテーブルと、そのテーブルと構造が全く同じ他のテーブル比較する方法をご紹介します。
SQLと言ってもデータベースによって多少異なりますが、今回はOracleをベースにご紹介していきたいと思います。
基本的なSQLは他のデータベースと変わりません。
今回使う演算子MINUSUNIONです!

目次

MINUS(EXCEPT)演算子

MINUSEXCEPTのどちらの演算子を使うかですが、MINUSOracleEXCEPTPostgreSQLSQLServerなどで使うそうな。

試してはないですが、OracleでもEXCEPTを使えるっぽいです。
もちろん結果は変わりません。

UNION(UNION ALL)演算子

次に検索結果を統合するUNION演算子です。
ここで気になるのが、似たような意味を持つJOINがありますが、これは統合“ではなく”結合なのでお間違えないように。
二つの意味を比較してみると、統合は重複する2つのデータがあれば1つにまとめる、結合は同じキーが存在したら後ろ(もしくは前)にくっつけるという意味です。
以下のサイトにUNIONに関する詳しい内容がありますので参考までに。

差分比較SQL

それでは、上記のMINUSUNIONを利用して2つの同じ構造のテーブルの差分を抽出するSQL文を作成します。
具体的には「差集合」と言うらしいです。
MINUSマイナス)はその名の通り、計算式で表すと「TABLE_A – TABLE_B」となります。
単純に差分を取得するだけなら、

となりますが、このままだと差分があっても片方のテーブルのレコードしか表示されないため、どのカラムで差分が発生しているか一目でわかりません。
比較するにはもう片方のデータも出力する必要があります。
その場合はテーブルを逆にしてMINUSしてあげれば良いです。

そして、これら2つの差分統合して一気に出力する場合はUNIONを使って、以下のようなSQL文を流します。

これで、全カラムでどれか1つでも差分があるデータを含む、TABLE_ATABLE_B両方のレコードを出力します。

【おまけ】もっと比較しやすく!

さらに!さらに!!
上記の方法だけでは、どちらのレコードが出力されているか判り辛いです。
そこで、テーブル名カラムとして出力しちゃって、さらに共通するキー項目(主キーなど)でソートしてあげましょう!

【おまけのおまけ】絞り込む!

もっと絞り込むためにWHERE句を付けましょうか。
SELECT文が4つあるので、普通ならそれぞれにWHERE句を付けるのですが、今回の例では2つのテーブル構造が全く同じなので、それでは大変面倒です。
そこで、WITH句を使ってまとめちゃいます!

ざっとこんな感じです。
説明すると、まず差分を検索した結果をWITH句を使って宣言したDIFFというビュー?(仮想のテーブル?)に入れちゃいます!
そして、最後にそのDIFFから、WHERE句でADDRESSJapanを含む差分のみを検索して結果を返しています。以上です!
いかがでしたでしょうか?
期待通りに動いて、皆さんのお役に立てれば幸いです。

著:渡部 亮太, 著:岡野 平八郎, 著:鈴木 俊也, 著:株式会社コーソル, 読み手:日本オラクル株式会社
¥3,762 (2024/02/22 14:17時点 | Amazon調べ)
著:株式会社コーソル, 著:渡部 亮太, 著:舛井 智行, 著:杉本 篤信, 著:西田 幸平, 読み手:日本オラクル株式会社
¥5,390 (2024/02/19 17:53時点 | Amazon調べ)
著:株式会社コーソル企画&マーケティング部, 著:渡部亮太, 著:舛井智行
¥8,250 (2024/02/22 16:21時点 | Amazon調べ)
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメント一覧 (2件)

  • 載せるSQLはちゃんとテストしましょう。

    OracleだとMINUSより先にUNION ALLが走る。

    • hogeraさん、ご指摘ありがとうございます!

      おっしゃる通り、OracleのSQLではMINUS演算子がUNION ALLよりも先に評価されます。
      このため、意図しない結果が得られる可能性があります。
      MINUSよりもUNION ALLが先に実行されると、その結果にMINUSが適用されることになり、期待する差分の抽出ができません。

      掲載していたSQLを改善しました。
      改善点として、UNION ALLとMINUSの間に括弧を追加し、それぞれの結果を明示的に区別しています。

コメントする

CAPTCHA


目次