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