Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLで差分を取得・抽出する2つの方法

SQLを操作する際に、2つのテーブルを比較する機会があると思います。

「あるテーブルには存在するデータだが、もう片方のテーブルには存在しないデータを取得したい」

このような、テーブル間での「差分」データを取得する方法についてこの記事では解説します。

方法はいくつかあるのですが、ここでは以下の2つの方法をご紹介します。

方法 特徴
差集合演算を使用 簡単に使えるが比較するテーブルのカラム数とデータ型を合わせる必要がある
SQLだけを使用 差分を取得する原理をしると、汎用的に使え応用が利く

 

差分の取得・抽出を理解するために、実際に操作して確認してみましょう。

ここでは、次の【販売テーブル】と【ユーザーテーブル】を用意して確認していきます。

それぞれのテーブルには、次の表のデータ・レコードを格納しました。

 

【販売テーブル】

sale_id sale_date sale_fee user_id
1 2020-08-01 5300 U101
2 2020-08-16 6000 U102
3 2020-09-07 8200 U103
4 2020-09-22 6500
5 2020-10-02 10200 U101
6 2020-10-18 8500 U400

【ユーザーテーブル】

user_id user_name user_address
U101 Satou Tokyo
U102 Ishida Osaka
U103 Ueki Tokyo

次の章で、差集合演算を使った取得・抽出方法を見ていきましょう!

【差集合演算】を使用して差分を取得・抽出

まずは、差集合演算を使用して差分を取得・抽出してみます。

各DBMSには、差分を演算するための組み込み関数が用意されているのです。

それぞれ、次の演算子になります。

DBMS名 演算子・関数
MySQL 対応なし
PostgreSQL EXCEPT演算子
Oracle MINUS演算子
SQL Server EXCEPT演算子
Access 対応なし

なお、MySQLにはMINUS演算子・EXCEPT演算子の対応がないため、後述するSQLだけを使用した差分の取得・抽出が必要です。

MINUS演算子・EXCEPT演算子は、あるSQLの結果セットから、もう片方のSQLの結果セットを引き算(差)した結果を返します。

MINUS演算子・EXCEPT演算子の記述方法は、次のようになります。

--MINUS演算子
SELECT カラム名1, カラム名2, … FROM テーブル名1
MINUS
SELECT カラム名1, カラム名2, … FROM テーブル名2

--EXCEPT演算子
SELECT カラム名1, カラム名2, … FROM テーブル名1
EXCEPT
SELECT カラム名1, カラム名2, … FROM テーブル名2

上記を見ての通り、記述方法は同じで使う演算子だけが異なります。

 

では実際に、先ほど用意したテーブルを使って確認してみましょう。

それぞれのテーブルのデータは次のように用意されています。

mydb=# SELECT * FROM sale_list;
 sale_id | sale_date  | sale_fee | user_id 
---------+------------+----------+---------
       1 | 2020-08-01 |     5300 | U101
       2 | 2020-08-16 |     6000 | U102
       3 | 2020-09-07 |     8200 | U103
       4 | 2020-09-22 |     6500 | 
       5 | 2020-10-02 |    10200 | U101
       6 | 2020-10-18 |     8500 | U400
(6 rows)

mydb=# SELECT * FROM user_list;
 user_id | user_name | user_address 
---------+-----------+--------------
 U101    | Satou     | Tokyo
 U102    | Ishida    | Osaka
 U103    | Ueki      | Tokyo
(3 rows)

ここでは、【販売テーブル】と【ユーザーテーブル】から user_idカラム の差集合を取得・抽出します。

記述方法は次の通りです。

SELECT user_id FROM sale_list EXCEPT SELECT user_id FROM user_list;

上記のSQL文を実行すると、次のデータを取得できました。

mydb=# SELECT user_id FROM sale_list EXCEPT SELECT user_id FROM user_list;
 user_id 
---------
 
 U400
(2 rows)

user_listテーブルに登録されていない NULL値 と U400 というデータが取得・抽出できています。

このように、差集合演算を使うとカンタンに目的のデータを取得・抽出可能です。

【SQLだけ】を使用して差分を取得・抽出

では次に、SQLだけを使用して差分を取得・抽出する方法をみていきましょう。

SQL操作でテーブル間の差を求める場合には、それぞれ異なった項目を持ったテーブルを比較することが多いはずです。

差集合演算はカンタンに使えて便利ですが、比較するテーブルの項目が全く同じでなければ、一部のデータ・項目しか取得・抽出できません。

そのため、場合によっては扱いにくいと感じてしまうのです。

 

一方で、SQLだけを使用して差分を取得・抽出を覚えておくと、どんなテーブルでも扱いやすくなるメリットがあります。

そのやり方は、「OUTER JOIN句」を使う方法です。

OUTER JOIN句は「外部結合」のことで、一致しないデータも含めて2つのテーブルを結合させ、テーブル間のデータをひとまとめにした情報を取得します。

OUTER JOIN句については、以下の記事で詳しく解説しているので参考までに。

【関連記事】

▶︎【SQL】外部結合でテーブルを結合させる。OUTER JOIN句について詳しく解説。

 

では実際に、OUTER JOIN句を使って2つのテーブルを外部結合してみます。

記述方法は次の通りです。

SELECT * FROM sale_list LEFT OUTER JOIN user_list ON (sale_list.user_id = user_list.user_id);

それぞれのテーブルの user_idカラム をもとに、sale_listテーブル に user_listテーブル を結合しています。

上記のSQL文を実行すると、次のような結果が取得できます。

mydb=# SELECT * FROM sale_list LEFT OUTER JOIN user_list ON (sale_list.user_id = user_list.user_id);
 sale_id | sale_date  | sale_fee | user_id | user_id | user_name | user_address 
---------+------------+----------+---------+---------+-----------+--------------
       1 | 2020-08-01 |     5300 | U101    | U101    | Satou     | Tokyo
       2 | 2020-08-16 |     6000 | U102    | U102    | Ishida    | Osaka
       3 | 2020-09-07 |     8200 | U103    | U103    | Ueki      | Tokyo
       4 | 2020-09-22 |     6500 |         |         |           | 
       5 | 2020-10-02 |    10200 | U101    | U101    | Satou     | Tokyo
       6 | 2020-10-18 |     8500 | U400    |         |           | 
(6 rows)

この結合したテーブルには NULL になっているデータがありますよね。

このデータこそ、それぞれのテーブルの「差分」となっているのです。

この NULL を条件にしてデータを取得すると、差分の取得ができそうです。

先ほどのSQL文に条件を付け足したものが、以下のSQL文になります。

SELECT * FROM sale_list LEFT OUTER JOIN user_list ON (sale_list.user_id = user_list.user_id) WHERE user_list.user_id IS NULL;

「WHERE user_list.user_id IS NULL」を追加しました。

これで、user_listテーブル の user_idカラム が NULL(登録なし) のデータを取得できます。

mydb=# SELECT * FROM sale_list LEFT OUTER JOIN user_list ON (sale_list.user_id = user_list.user_id) WHERE user_list.user_id IS NULL;
 sale_id | sale_date  | sale_fee | user_id | user_id | user_name | user_address 
---------+------------+----------+---------+---------+-----------+--------------
       4 | 2020-09-22 |     6500 |         |         |           | 
       6 | 2020-10-18 |     8500 | U400    |         |           | 
(2 rows)

上記のように、期待した通りの結果になっているはずです。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。