MySQL
 Computer >> コンピューター >  >> プログラミング >> MySQL

【MySQL】別のテーブルに存在しないレコードを抽出する方法(NOT IN句の使い方)

MySQLであるテーブルから、別のテーブルには存在しないレコードだけを抽出したい場合があります。そんなときは、サブクエリ(副問い合わせ)NOT IN句を組み合わせることで簡単に実現できます。

この記事では、実際にテーブルを作成しながら、その手順をステップごとにわかりやすく解説します。

1. 最初のテーブル「PresentHistory」を作成する

まず、CREATE文を使って2つのカラムを持つテーブル「PresentHistory」を作成します。

mysql> CREATE table PresentHistory
-> (
-> HisID int,
-> HisName varchar(100)
-> );
Query OK, 0 rows affected (0.54 sec)

2. PresentHistoryにレコードを挿入する

次に、INSERT文でレコードを追加します。これらのレコードは後ほど作成する2つ目のテーブルにも存在することになります。

mysql> INSERT into PresentHistory values(1,'John');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PresentHistory values(2,'Bob');
Query OK, 1 row affected (0.15 sec)

SELECT文でデータが正しく登録されたか確認してみましょう。

mysql> SELECT * from PresentHistory;

実行結果は以下の通りです。

+-------+---------+
| HisID | HisName |
+-------+---------+
| 1 | John |
| 2 | Bob |
+-------+---------+
2 rows in set (0.00 sec)

3. 2つ目のテーブル「PastHistory」を作成する

続いて、比較対象となる2つ目のテーブル「PastHistory」を作成します。こちらも2つのカラムを持つ構造です。

mysql> CREATE table PastHistory
-> (
-> PastId int,
-> PastName varchar(100)
-> );
Query OK, 0 rows affected (0.74 sec)

4. PastHistoryにレコードを挿入する

PastHistoryには、最初のテーブルに存在するレコードと、存在しないレコードの両方を挿入します。

mysql> INSERT into PastHistory values(1,'John');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PastHistory values(2,'Bob');
Query OK, 1 row affected (0.13 sec)

mysql> INSERT into PastHistory values(3,'Carol');
Query OK, 1 row affected (0.17 sec)

mysql> INSERT into PastHistory values(4,'Jason');
Query OK, 1 row affected (0.16 sec)

これでPastHistoryには合計4件のレコードが登録されました。うち2件はPresentHistoryと共通しており、残り2件(Carol、Jason)はPresentHistoryには存在しないレコードです。

SELECT文で内容を確認します。

mysql> SELECT * from PastHistory;

実行結果は以下の通りです。

+--------+----------+
| PastId | PastName |
+--------+----------+
| 1 | John |
| 2 | Bob |
| 3 | Carol |
| 4 | Jason |
+--------+----------+
4 rows in set (0.00 sec)

5. NOT IN句とサブクエリで差分を抽出する

あるテーブルに存在しないレコードを別のテーブルから取得するための基本構文は以下の通りです。

SELECT * from yourSecondTableName where columnNamefromSecondtable NOT IN
(SELECT columnNamefromfirsttable from yourFirstTableName);

この構文に従って、PastHistoryの中からPresentHistoryに存在しないレコードを取得するクエリを実行します。

mysql> SELECT * from PastHistory where PastName not in (select HisName from
PresentHistory);

実行結果は以下の通りです。

+--------+----------+
| PastId | PastName |
+--------+----------+
| 3 | Carol |
| 4 | Jason |
+--------+----------+
2 rows in set (0.00 sec)

まとめ

実行結果から、「Carol」と「Jason」の2件がPresentHistoryには存在しないレコードとして正しく抽出できたことがわかります。このように、NOT IN句とサブクエリを組み合わせれば、テーブル間の差分をシンプルなSQLで効率的に取得できます。

なお、大量のデータを扱う場合はパフォーマンスの観点からLEFT JOIN ... IS NULLやEXISTS句を使う方法も検討するとよいでしょう。

  1. 【MySQL】別のテーブルのデータを参照してテーブルを更新する方法(UPDATE+JOIN)

    MySQLでは、UPDATEコマンドとJOINを組み合わせることで、別のテーブルのデータを参照しながら、対象のテーブルを効率的に更新できます。本記事では、2つのテーブルを使った具体的なサンプルを通じて、その手順をわかりやすく解説します。 手順1:参照元のテーブルを作成する まず、氏名データを保持する1つ目のテーブル「demo54」を作成します。 mysql> create table demo54-> (-> firstName varchar(20),-> lastName varchar(20)-> );Query OK, 0 rows affected (

  2. MySQLであるテーブルから別のテーブルへデータを挿入する方法(INSERT INTO SELECT)

    MySQLであるテーブルから別のテーブルへデータをコピーして挿入したい場合は、INSERT INTO ... SELECT 文を使用します。この記事では、実際にテーブルを作成し、データを別テーブルへ移す手順をサンプルコードと実行結果とともにわかりやすく解説します。 1. 元となるテーブルを作成する まず、コピー元となるテーブル「DemoTable1」を作成します。カラムは Id(int型)と FirstName(varchar型)の2つです。 mysql> create table DemoTable1 -> ( -> Id int, -> Fi